summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Entities/ArrowEntity.cpp16
-rw-r--r--src/Entities/ArrowEntity.h6
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp17
-rw-r--r--src/WorldStorage/WSSAnvil.cpp11
4 files changed, 31 insertions, 19 deletions
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp
index 7e96a666d..c039b0b3c 100644
--- a/src/Entities/ArrowEntity.cpp
+++ b/src/Entities/ArrowEntity.cpp
@@ -67,15 +67,15 @@ bool cArrowEntity::CanPickup(const cPlayer & a_Player) const
void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
-{
+{
+ if (GetSpeed().SqrLength() == 0)
+ {
+ SetSpeed(GetLookVector().NormalizeCopy() * 0.1); // Ensure that no division by zero happens later
+ }
+
Vector3d Hit = a_HitPos;
- Vector3d SinkMovement = GetSpeed() / 800; // Base value for arrow penetration
- SinkMovement = Clamp( // Adjust the movement so that fast arrows don't go through blocks (though in reality they would, in addition to exploding into fragments :P)
- SinkMovement,
- (SinkMovement * 0.001) / SinkMovement.Length(),
- (SinkMovement * 0.05) / SinkMovement.Length()
- );
- Hit += SinkMovement; // Make arrow sink into block a little
+ Vector3d SinkMovement = (GetSpeed() / 800);
+ Hit += (SinkMovement * 0.01) / SinkMovement.Length(); // Make arrow sink into block a centimetre so it lodges (but not to far so it goes black clientside)
super::OnHitSolidBlock(Hit, a_HitFace);
Vector3i BlockHit = Hit.Floor();
diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h
index 1fe3032ee..99b7bae31 100644
--- a/src/Entities/ArrowEntity.h
+++ b/src/Entities/ArrowEntity.h
@@ -58,8 +58,14 @@ public:
/// Sets the IsCritical flag
void SetIsCritical(bool a_IsCritical) { m_IsCritical = a_IsCritical; }
+
+ /** Gets the block arrow is in */
+ Vector3i GetBlockHit(void) const { return m_HitBlockPos; }
// tolua_end
+
+ /** Sets the block arrow is in */
+ void SetBlockHit(const Vector3i & a_BlockHit) { m_HitBlockPos = a_BlockHit; }
protected:
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 8294d4a00..e49042ff7 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -589,20 +589,19 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
m_Writer.BeginCompound("");
AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName());
Vector3d Pos = a_Projectile->GetPosition();
- m_Writer.AddShort("xTile", (Int16)floor(Pos.x));
- m_Writer.AddShort("yTile", (Int16)floor(Pos.y));
- m_Writer.AddShort("zTile", (Int16)floor(Pos.z));
- m_Writer.AddShort("inTile", 0); // TODO: Query the block type
- m_Writer.AddShort("shake", 0); // TODO: Any shake?
- m_Writer.AddByte ("inGround", a_Projectile->IsInGround() ? 1 : 0);
+ m_Writer.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0);
switch (a_Projectile->GetProjectileKind())
{
case cProjectileEntity::pkArrow:
{
- m_Writer.AddByte("inData", 0); // TODO: Query the block meta (is it needed?)
- m_Writer.AddByte("pickup", ((cArrowEntity *)a_Projectile)->GetPickupState());
- m_Writer.AddDouble("damage", ((cArrowEntity *)a_Projectile)->GetDamageCoeff());
+ cArrowEntity * Arrow = (cArrowEntity *)a_Projectile;
+
+ m_Writer.AddInt("xTile", (Int16)Arrow->GetBlockHit().x);
+ m_Writer.AddInt("yTile", (Int16)Arrow->GetBlockHit().y);
+ m_Writer.AddInt("zTile", (Int16)Arrow->GetBlockHit().z);
+ m_Writer.AddByte("pickup", Arrow->GetPickupState());
+ m_Writer.AddDouble("damage", Arrow->GetDamageCoeff());
break;
}
case cProjectileEntity::pkGhastFireball:
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index 0f84a0eb1..1e9ce80cc 100644
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -1656,6 +1656,15 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
Arrow->SetDamageCoeff(a_NBT.GetDouble(DamageIdx));
}
+ // Load block hit:
+ int InBlockXIdx = a_NBT.FindChildByName(a_TagIdx, "xTile");
+ int InBlockYIdx = a_NBT.FindChildByName(a_TagIdx, "yTile");
+ int InBlockZIdx = a_NBT.FindChildByName(a_TagIdx, "zTile");
+ if ((InBlockXIdx > 0) && (InBlockYIdx > 0) && (InBlockZIdx > 0))
+ {
+ Arrow->SetBlockHit(Vector3i(a_NBT.GetInt(InBlockXIdx), a_NBT.GetInt(InBlockYIdx), a_NBT.GetInt(InBlockZIdx)));
+ }
+
// Store the new arrow in the entities list:
a_Entities.push_back(Arrow.release());
}
@@ -2481,8 +2490,6 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP
}
a_Entity.SetIsInGround(IsInGround);
- // TODO: Load inTile, TileCoords
-
return true;
}