summaryrefslogtreecommitdiffstats
path: root/source/WorldStorage
diff options
context:
space:
mode:
Diffstat (limited to 'source/WorldStorage')
-rw-r--r--source/WorldStorage/NBTChunkSerializer.cpp67
-rw-r--r--source/WorldStorage/NBTChunkSerializer.h2
-rw-r--r--source/WorldStorage/WSSAnvil.cpp51
-rw-r--r--source/WorldStorage/WSSAnvil.h1
4 files changed, 113 insertions, 8 deletions
diff --git a/source/WorldStorage/NBTChunkSerializer.cpp b/source/WorldStorage/NBTChunkSerializer.cpp
index 706e913ef..baae0dc01 100644
--- a/source/WorldStorage/NBTChunkSerializer.cpp
+++ b/source/WorldStorage/NBTChunkSerializer.cpp
@@ -22,6 +22,8 @@
#include "../Entities/Minecart.h"
#include "../Mobs/Monster.h"
#include "../Entities/Pickup.h"
+#include "../Entities/ProjectileEntity.h"
+
@@ -330,6 +332,62 @@ void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup)
+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 (is it needed?)
+ m_Writer.AddShort("shake", 0); // TODO: Any shake?
+ 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());
+ break;
+ }
+ case cProjectileEntity::pkGhastFireball:
+ {
+ m_Writer.AddInt("ExplosionPower", 1);
+ // fall-through:
+ }
+ case cProjectileEntity::pkFireCharge:
+ case cProjectileEntity::pkWitherSkull:
+ {
+ m_Writer.BeginList("Motion", TAG_Double);
+ m_Writer.AddDouble("", a_Projectile->GetSpeedX());
+ m_Writer.AddDouble("", a_Projectile->GetSpeedY());
+ m_Writer.AddDouble("", a_Projectile->GetSpeedZ());
+ m_Writer.EndList();
+ break;
+ }
+ default:
+ {
+ ASSERT(!"Unsaved projectile entity!");
+ }
+ } // switch (ProjectileKind)
+ cEntity * Creator = a_Projectile->GetCreator();
+ if (Creator != NULL)
+ {
+ if (Creator->GetEntityType() == cEntity::etPlayer)
+ {
+ m_Writer.AddString("ownerName", ((cPlayer *)Creator)->GetName());
+ }
+ }
+ m_Writer.EndCompound();
+}
+
+
+
+
+
void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart)
{
m_Writer.BeginList("Items", TAG_Compound);
@@ -403,10 +461,11 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity)
switch (a_Entity->GetEntityType())
{
- case cEntity::etFallingBlock: AddFallingBlockEntity((cFallingBlock *)a_Entity); break;
- case cEntity::etMinecart: AddMinecartEntity ((cMinecart *) a_Entity); break;
- case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break;
- case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break;
+ case cEntity::etFallingBlock: AddFallingBlockEntity((cFallingBlock *) a_Entity); break;
+ case cEntity::etMinecart: AddMinecartEntity ((cMinecart *) a_Entity); break;
+ case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break;
+ case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break;
+ case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break;
case cEntity::etPlayer: return; // Players aren't saved into the world
default:
{
diff --git a/source/WorldStorage/NBTChunkSerializer.h b/source/WorldStorage/NBTChunkSerializer.h
index cd1388f89..481c578f3 100644
--- a/source/WorldStorage/NBTChunkSerializer.h
+++ b/source/WorldStorage/NBTChunkSerializer.h
@@ -36,6 +36,7 @@ class cMinecartWithHopper;
class cMonster;
class cPickup;
class cItemGrid;
+class cProjectileEntity;
@@ -97,6 +98,7 @@ protected:
void AddMinecartEntity (cMinecart * a_Minecart);
void AddMonsterEntity (cMonster * a_Monster);
void AddPickupEntity (cPickup * a_Pickup);
+ void AddProjectileEntity (cProjectileEntity * a_Projectile);
void AddMinecartChestContents(cMinecartWithChest * a_Minecart);
diff --git a/source/WorldStorage/WSSAnvil.cpp b/source/WorldStorage/WSSAnvil.cpp
index 72d583e2b..3ab64148e 100644
--- a/source/WorldStorage/WSSAnvil.cpp
+++ b/source/WorldStorage/WSSAnvil.cpp
@@ -20,13 +20,13 @@
#include "../Item.h"
#include "../ItemGrid.h"
#include "../StringCompression.h"
-#include "../Entities/Entity.h"
#include "../OSSupport/MakeDir.h"
#include "FastNBT.h"
+#include "../Mobs/Monster.h"
#include "../Entities/FallingBlock.h"
#include "../Entities/Minecart.h"
-#include "../Mobs/Monster.h"
#include "../Entities/Pickup.h"
+#include "../Entities/ProjectileEntity.h"
@@ -956,6 +956,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
LoadPickupFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
}
+ if (strncmp(a_IDTag, "Arrow", a_IDTagLength) == 0)
+ {
+ LoadArrowFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
+ }
// TODO: other entities
}
@@ -1043,7 +1047,7 @@ void cWSSAnvil::LoadMinecartTFromNBT(cEntityList & a_Entities, const cParsedNBT
return;
}
- //TODO: Everything to do with TNT carts
+ // TODO: Everything to do with TNT carts
a_Entities.push_back(Minecart.release());
}
@@ -1060,7 +1064,7 @@ void cWSSAnvil::LoadMinecartHFromNBT(cEntityList & a_Entities, const cParsedNBT
return;
}
- //TODO: Everything to do with hopper carts
+ // TODO: Everything to do with hopper carts
a_Entities.push_back(Minecart.release());
}
@@ -1093,6 +1097,45 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a
+void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
+{
+ std::auto_ptr<cArrowEntity> Arrow(new cArrowEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0)));
+ if (!LoadEntityBaseFromNBT(*Arrow.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ // Load pickup state:
+ int PickupIdx = a_NBT.FindChildByName(a_TagIdx, "pickup");
+ if (PickupIdx > 0)
+ {
+ Arrow->SetPickupState((cArrowEntity::ePickupState)a_NBT.GetByte(PickupIdx));
+ }
+ else
+ {
+ // Try the older "player" tag:
+ int PlayerIdx = a_NBT.FindChildByName(a_TagIdx, "player");
+ if (PlayerIdx > 0)
+ {
+ Arrow->SetPickupState((a_NBT.GetByte(PlayerIdx) == 0) ? cArrowEntity::psNoPickup : cArrowEntity::psInSurvivalOrCreative);
+ }
+ }
+
+ // Load damage:
+ int DamageIdx = a_NBT.FindChildByName(a_TagIdx, "damage");
+ if (DamageIdx > 0)
+ {
+ Arrow->SetDamageCoeff(a_NBT.GetDouble(DamageIdx));
+ }
+
+ // Store the new arrow in the entities list:
+ a_Entities.push_back(Arrow.release());
+}
+
+
+
+
+
bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx)
{
double Pos[3];
diff --git a/source/WorldStorage/WSSAnvil.h b/source/WorldStorage/WSSAnvil.h
index 47fda3f7b..b2556ab50 100644
--- a/source/WorldStorage/WSSAnvil.h
+++ b/source/WorldStorage/WSSAnvil.h
@@ -145,6 +145,7 @@ protected:
void LoadMinecartTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadMinecartHFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
+ void LoadArrowFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
/// Loads entity common data from the NBT compound; returns true if successful
bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx);