diff options
-rw-r--r-- | src/Entities/ArrowEntity.cpp | 16 | ||||
-rw-r--r-- | src/Entities/ArrowEntity.h | 6 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.cpp | 17 | ||||
-rw-r--r-- | src/WorldStorage/WSSAnvil.cpp | 11 |
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; } |