diff options
Diffstat (limited to '')
-rw-r--r-- | src/WorldStorage/FastNBT.h | 56 | ||||
-rw-r--r-- | src/WorldStorage/FireworksSerializer.h | 2 | ||||
-rw-r--r-- | src/WorldStorage/MapSerializer.cpp | 6 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.cpp | 21 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.h | 2 | ||||
-rw-r--r-- | src/WorldStorage/SchematicFileSerializer.cpp | 43 | ||||
-rw-r--r-- | src/WorldStorage/WSSAnvil.cpp | 27 | ||||
-rw-r--r-- | src/WorldStorage/WSSAnvil.h | 1 |
8 files changed, 121 insertions, 37 deletions
diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index 1b8b09c21..5e5af3ca3 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -122,33 +122,33 @@ public: int GetRoot(void) const {return 0; } /** Returns the first child of the specified tag, or -1 if none / not applicable. */ - int GetFirstChild (int a_Tag) const { return m_Tags[a_Tag].m_FirstChild; } + int GetFirstChild (int a_Tag) const { return m_Tags[(size_t)a_Tag].m_FirstChild; } /** Returns the last child of the specified tag, or -1 if none / not applicable. */ - int GetLastChild (int a_Tag) const { return m_Tags[a_Tag].m_LastChild; } + int GetLastChild (int a_Tag) const { return m_Tags[(size_t)a_Tag].m_LastChild; } /** Returns the next sibling of the specified tag, or -1 if none. */ - int GetNextSibling(int a_Tag) const { return m_Tags[a_Tag].m_NextSibling; } + int GetNextSibling(int a_Tag) const { return m_Tags[(size_t)a_Tag].m_NextSibling; } /** Returns the previous sibling of the specified tag, or -1 if none. */ - int GetPrevSibling(int a_Tag) const { return m_Tags[a_Tag].m_PrevSibling; } + int GetPrevSibling(int a_Tag) const { return m_Tags[(size_t)a_Tag].m_PrevSibling; } /** Returns the length of the tag's data, in bytes. Not valid for Compound or List tags! */ int GetDataLength (int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type != TAG_List); - ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); - return m_Tags[a_Tag].m_DataLength; + ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_List); + ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_Compound); + return m_Tags[(size_t)a_Tag].m_DataLength; } /** Returns the data stored in this tag. Not valid for Compound or List tags! */ const char * GetData(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type != TAG_List); - ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); - return m_Data + m_Tags[a_Tag].m_DataStart; + ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_List); + ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_Compound); + return m_Data + m_Tags[(size_t)a_Tag].m_DataStart; } /** Returns the direct child tag of the specified name, or -1 if no such tag. */ @@ -163,47 +163,47 @@ public: /** Returns the child tag of the specified path (Name1\Name2\Name3...), or -1 if no such tag. */ int FindTagByPath(int a_Tag, const AString & a_Path) const; - eTagType GetType(int a_Tag) const { return m_Tags[a_Tag].m_Type; } + eTagType GetType(int a_Tag) const { return m_Tags[(size_t)a_Tag].m_Type; } /** Returns the children type for a List tag; undefined on other tags. If list empty, returns TAG_End. */ eTagType GetChildrenType(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_List); - return (m_Tags[a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[m_Tags[a_Tag].m_FirstChild].m_Type; + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_List); + return (m_Tags[(size_t)a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[(size_t)m_Tags[(size_t)a_Tag].m_FirstChild].m_Type; } /** Returns the value stored in a Byte tag. Not valid for any other tag type. */ inline unsigned char GetByte(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Byte); - return (unsigned char)(m_Data[m_Tags[a_Tag].m_DataStart]); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Byte); + return (unsigned char)(m_Data[(size_t)m_Tags[(size_t)a_Tag].m_DataStart]); } /** Returns the value stored in a Short tag. Not valid for any other tag type. */ inline Int16 GetShort(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Short); - return GetBEShort(m_Data + m_Tags[a_Tag].m_DataStart); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Short); + return GetBEShort(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); } /** Returns the value stored in an Int tag. Not valid for any other tag type. */ inline Int32 GetInt(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Int); - return GetBEInt(m_Data + m_Tags[a_Tag].m_DataStart); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Int); + return GetBEInt(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); } /** Returns the value stored in a Long tag. Not valid for any other tag type. */ inline Int64 GetLong(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Long); - return NetworkToHostLong8(m_Data + m_Tags[a_Tag].m_DataStart); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Long); + return NetworkToHostLong8(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); } /** Returns the value stored in a Float tag. Not valid for any other tag type. */ inline float GetFloat(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Float); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Float); // Cause a compile-time error if sizeof(float) != 4 // If your platform produces a compiler error here, you'll need to add code that manually decodes 32-bit floats @@ -212,7 +212,7 @@ public: UNUSED(Check1); UNUSED(Check2); - Int32 i = GetBEInt(m_Data + m_Tags[a_Tag].m_DataStart); + Int32 i = GetBEInt(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); float f; memcpy(&f, &i, sizeof(f)); return f; @@ -228,16 +228,16 @@ public: UNUSED(Check1); UNUSED(Check2); - ASSERT(m_Tags[a_Tag].m_Type == TAG_Double); - return NetworkToHostDouble8(m_Data + m_Tags[a_Tag].m_DataStart); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Double); + return NetworkToHostDouble8(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); } /** Returns the value stored in a String tag. Not valid for any other tag type. */ inline AString GetString(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_String); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_String); AString res; - res.assign(m_Data + m_Tags[a_Tag].m_DataStart, m_Tags[a_Tag].m_DataLength); + res.assign(m_Data + m_Tags[(size_t)a_Tag].m_DataStart, m_Tags[(size_t)a_Tag].m_DataLength); return res; } @@ -245,7 +245,7 @@ public: inline AString GetName(int a_Tag) const { AString res; - res.assign(m_Data + m_Tags[a_Tag].m_NameStart, m_Tags[a_Tag].m_NameLength); + res.assign(m_Data + m_Tags[(size_t)a_Tag].m_NameStart, m_Tags[(size_t)a_Tag].m_NameLength); return res; } diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h index 5b87bafdb..cbc544a14 100644 --- a/src/WorldStorage/FireworksSerializer.h +++ b/src/WorldStorage/FireworksSerializer.h @@ -89,4 +89,4 @@ public: short m_FlightTimeInTicks; std::vector<int> m_Colours; std::vector<int> m_FadeColours; -};
\ No newline at end of file +}; diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index a4a0aab57..df72d1cc9 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -141,7 +141,11 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) { eDimension Dimension = (eDimension) a_NBT.GetByte(CurrLine); - ASSERT(Dimension == m_Map->m_World->GetDimension()); + if (Dimension != m_Map->m_World->GetDimension()) + { + // TODO 2014-03-20 xdot: We should store nether maps in nether worlds, e.t.c. + return false; + } } CurrLine = a_NBT.FindChildByName(Data, "width"); diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index acca96ba8..415693ae2 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -23,6 +23,7 @@ #include "../BlockEntities/FlowerPotEntity.h" #include "../Entities/Entity.h" +#include "../Entities/EnderCrystal.h" #include "../Entities/FallingBlock.h" #include "../Entities/Boat.h" #include "../Entities/Minecart.h" @@ -43,6 +44,7 @@ #include "../Mobs/Slime.h" #include "../Mobs/Skeleton.h" #include "../Mobs/Villager.h" +#include "../Mobs/Wither.h" #include "../Mobs/Wolf.h" #include "../Mobs/Zombie.h" @@ -335,6 +337,17 @@ void cNBTChunkSerializer::AddBoatEntity(cBoat * a_Boat) +void cNBTChunkSerializer::AddEnderCrystalEntity(cEnderCrystal * a_EnderCrystal) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_EnderCrystal, "EnderCrystal"); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock) { m_Writer.BeginCompound(""); @@ -422,7 +435,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) case cMonster::mtSquid: EntityClass = "Squid"; break; case cMonster::mtVillager: EntityClass = "Villager"; break; case cMonster::mtWitch: EntityClass = "Witch"; break; - case cMonster::mtWither: EntityClass = "Wither"; break; + case cMonster::mtWither: EntityClass = "WitherBoss"; break; case cMonster::mtWolf: EntityClass = "Wolf"; break; case cMonster::mtZombie: EntityClass = "Zombie"; break; case cMonster::mtZombiePigman: EntityClass = "PigZombie"; break; @@ -501,6 +514,11 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddInt("Profession", ((const cVillager *)a_Monster)->GetVilType()); break; } + case cMonster::mtWither: + { + m_Writer.AddInt("Invul", ((const cWither *)a_Monster)->GetNumInvulnerableTicks()); + break; + } case cMonster::mtWolf: { m_Writer.AddString("Owner", ((const cWolf *)a_Monster)->GetOwner()); @@ -729,6 +747,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) switch (a_Entity->GetEntityType()) { case cEntity::etBoat: AddBoatEntity ((cBoat *) a_Entity); break; + case cEntity::etEnderCrystal: AddEnderCrystalEntity((cEnderCrystal *) 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; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index c1134cd00..51d104970 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -24,6 +24,7 @@ class cChestEntity; class cCommandBlockEntity; class cDispenserEntity; class cDropperEntity; +class cEnderCrystal; class cFurnaceEntity; class cHopperEntity; class cJukeboxEntity; @@ -106,6 +107,7 @@ protected: // Entities: void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); void AddBoatEntity (cBoat * a_Boat); + void AddEnderCrystalEntity(cEnderCrystal * a_EnderCrystal); void AddFallingBlockEntity(cFallingBlock * a_FallingBlock); void AddMinecartEntity (cMinecart * a_Minecart); void AddMonsterEntity (cMonster * a_Monster); diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index ef67fdb13..9d594a084 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -14,6 +14,39 @@ +#ifdef SELF_TEST + +static class cSchematicStringSelfTest +{ +public: + cSchematicStringSelfTest(void) + { + cBlockArea ba; + ba.Create(21, 256, 21); + ba.RelLine(0, 0, 0, 9, 8, 7, cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_WOODEN_STAIRS, 1); + AString Schematic; + if (!cSchematicFileSerializer::SaveToSchematicString(ba, Schematic)) + { + assert_test(!"Schematic failed to save!"); + } + cBlockArea ba2; + if (!cSchematicFileSerializer::LoadFromSchematicString(ba2, Schematic)) + { + assert_test(!"Schematic failed to load!"); + } + } +} g_SelfTest; + +#endif + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cSchematicFileSerializer: + bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName) { // Un-GZip the contents: @@ -197,7 +230,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP } // Copy the block types and metas: - int NumBytes = a_BlockArea.m_SizeX * a_BlockArea.m_SizeY * a_BlockArea.m_SizeZ; + int NumBytes = a_BlockArea.GetBlockCount(); if (a_NBT.GetDataLength(TBlockTypes) < NumBytes) { LOG("BlockTypes truncated in the schematic file (exp %d, got %d bytes). Loading partial.", @@ -209,7 +242,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP if (AreMetasPresent) { - int NumBytes = a_BlockArea.m_SizeX * a_BlockArea.m_SizeY * a_BlockArea.m_SizeZ; + int NumBytes = a_BlockArea.GetBlockCount(); if (a_NBT.GetDataLength(TBlockMetas) < NumBytes) { LOG("BlockMetas truncated in the schematic file (exp %d, got %d bytes). Loading partial.", @@ -230,9 +263,9 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockArea) { cFastNBTWriter Writer("Schematic"); - Writer.AddShort("Width", a_BlockArea.m_SizeX); - Writer.AddShort("Height", a_BlockArea.m_SizeY); - Writer.AddShort("Length", a_BlockArea.m_SizeZ); + Writer.AddShort("Width", a_BlockArea.m_Size.x); + Writer.AddShort("Height", a_BlockArea.m_Size.y); + Writer.AddShort("Length", a_BlockArea.m_Size.z); Writer.AddString("Materials", "Alpha"); if (a_BlockArea.HasBlockTypes()) { diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 7a2366755..48934d074 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -32,6 +32,7 @@ #include "../Mobs/IncludeAllMonsters.h" #include "../Entities/Boat.h" +#include "../Entities/EnderCrystal.h" #include "../Entities/FallingBlock.h" #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" @@ -1057,6 +1058,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadBoatFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "EnderCrystal", a_IDTagLength) == 0) + { + LoadEnderCrystalFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } else if (strncmp(a_IDTag, "FallingBlock", a_IDTagLength) == 0) { LoadFallingBlockFromNBT(a_Entities, a_NBT, a_EntityTagIdx); @@ -1238,7 +1243,7 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadWitchFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } - else if (strncmp(a_IDTag, "Wither", a_IDTagLength) == 0) + else if (strncmp(a_IDTag, "WitherBoss", a_IDTagLength) == 0) { LoadWitherFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } @@ -1275,6 +1280,20 @@ void cWSSAnvil::LoadBoatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N +void cWSSAnvil::LoadEnderCrystalFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr<cEnderCrystal> EnderCrystal(new cEnderCrystal(0, 0, 0)); + if (!LoadEntityBaseFromNBT(*EnderCrystal.get(), a_NBT, a_TagIdx)) + { + return; + } + a_Entities.push_back(EnderCrystal.release()); +} + + + + + void cWSSAnvil::LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "TileID"); @@ -2250,6 +2269,12 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a return; } + int CurrLine = a_NBT.FindChildByName(a_TagIdx, "Invul"); + if (CurrLine > 0) + { + Monster->SetNumInvulnerableTicks(a_NBT.GetInt(CurrLine)); + } + a_Entities.push_back(Monster.release()); } diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 50d0e555e..1773ee882 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -148,6 +148,7 @@ protected: void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength); void LoadBoatFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadEnderCrystalFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFallingBlockFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); |