Bulk clearing of whitespace
This commit is contained in:
@@ -9,7 +9,7 @@ void EnchantmentSerializer::WriteToNBTCompound(const cEnchantments & a_Enchantme
|
||||
{
|
||||
// Write the enchantments into the specified NBT writer
|
||||
// begin with the LIST tag of the specified name ("ench" or "StoredEnchantments")
|
||||
|
||||
|
||||
a_Writer.BeginList(a_ListTagName, TAG_Compound);
|
||||
for (cEnchantments::cMap::const_iterator itr = a_Enchantments.m_Enchantments.begin(), end = a_Enchantments.m_Enchantments.end(); itr != end; ++itr)
|
||||
{
|
||||
@@ -38,7 +38,7 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c
|
||||
ASSERT(!"Bad EnchListTag type");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Verify that the list is of Compounds:
|
||||
if (a_NBT.GetChildrenType(a_EnchListTagIdx) != TAG_Compound)
|
||||
{
|
||||
@@ -48,15 +48,15 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c
|
||||
ASSERT(!"Bad EnchListTag children type");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
a_Enchantments.Clear();
|
||||
|
||||
|
||||
// Iterate over all the compound children, parse an enchantment from each:
|
||||
for (int tag = a_NBT.GetFirstChild(a_EnchListTagIdx); tag >= 0; tag = a_NBT.GetNextSibling(tag))
|
||||
{
|
||||
// tag is the compound inside the "ench" list tag
|
||||
ASSERT(a_NBT.GetType(tag) == TAG_Compound);
|
||||
|
||||
|
||||
// Search for the id and lvl tags' values:
|
||||
int id = -1, lvl = -1;
|
||||
for (int ch = a_NBT.GetFirstChild(tag); ch >= 0; ch = a_NBT.GetNextSibling(ch))
|
||||
@@ -74,13 +74,13 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c
|
||||
lvl = a_NBT.GetShort(ch);
|
||||
}
|
||||
} // for ch - children of the compound tag
|
||||
|
||||
|
||||
if ((id == -1) || (lvl <= 0))
|
||||
{
|
||||
// Failed to parse either the id or the lvl, skip this compound
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Store the enchantment:
|
||||
a_Enchantments.m_Enchantments[id] = static_cast<unsigned int>(lvl);
|
||||
} // for tag - children of the ench list tag
|
||||
|
||||
@@ -14,10 +14,10 @@ namespace EnchantmentSerializer
|
||||
|
||||
/** Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") */
|
||||
void WriteToNBTCompound(const cEnchantments & a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName);
|
||||
|
||||
|
||||
/** Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) */
|
||||
void ParseFromNBT(cEnchantments & a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -69,16 +69,16 @@ bool cParsedNBT::Parse(void)
|
||||
// The top-level tag must be a Compound
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_Tags.reserve(NBT_RESERVE_SIZE);
|
||||
|
||||
|
||||
m_Tags.push_back(cFastNBTTag(TAG_Compound, -1));
|
||||
|
||||
|
||||
m_Pos = 1;
|
||||
|
||||
|
||||
RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
|
||||
RETURN_FALSE_IF_FALSE(ReadCompound());
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ bool cParsedNBT::ReadCompound(void)
|
||||
bool cParsedNBT::ReadList(eTagType a_ChildrenType)
|
||||
{
|
||||
// Reads the latest tag as a list of items of type a_ChildrenType
|
||||
|
||||
|
||||
// Read the count:
|
||||
NEEDBYTES(4);
|
||||
int Count = GetBEInt(m_Data + m_Pos);
|
||||
@@ -190,7 +190,7 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType)
|
||||
m_Pos += LEN; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
|
||||
bool cParsedNBT::ReadTag(void)
|
||||
{
|
||||
cFastNBTTag & Tag = m_Tags.back();
|
||||
@@ -202,12 +202,12 @@ bool cParsedNBT::ReadTag(void)
|
||||
CASE_SIMPLE_TAG(Long, 8)
|
||||
CASE_SIMPLE_TAG(Float, 4)
|
||||
CASE_SIMPLE_TAG(Double, 8)
|
||||
|
||||
|
||||
case TAG_String:
|
||||
{
|
||||
return ReadString(Tag.m_DataStart, Tag.m_DataLength);
|
||||
}
|
||||
|
||||
|
||||
case TAG_ByteArray:
|
||||
{
|
||||
NEEDBYTES(4);
|
||||
@@ -224,7 +224,7 @@ bool cParsedNBT::ReadTag(void)
|
||||
m_Pos += static_cast<size_t>(len);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
case TAG_List:
|
||||
{
|
||||
NEEDBYTES(1);
|
||||
@@ -233,13 +233,13 @@ bool cParsedNBT::ReadTag(void)
|
||||
RETURN_FALSE_IF_FALSE(ReadList(ItemType));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
case TAG_Compound:
|
||||
{
|
||||
RETURN_FALSE_IF_FALSE(ReadCompound());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
case TAG_IntArray:
|
||||
{
|
||||
NEEDBYTES(4);
|
||||
@@ -257,7 +257,7 @@ bool cParsedNBT::ReadTag(void)
|
||||
m_Pos += static_cast<size_t>(len);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(__clang__)
|
||||
default:
|
||||
#endif
|
||||
@@ -284,7 +284,7 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (a_NameLength == 0)
|
||||
{
|
||||
a_NameLength = strlen(a_Name);
|
||||
@@ -328,7 +328,7 @@ int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const
|
||||
}
|
||||
Begin = i + 1;
|
||||
} // for i - a_Path[]
|
||||
|
||||
|
||||
if (Begin < Length)
|
||||
{
|
||||
Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin);
|
||||
@@ -363,9 +363,9 @@ void cFastNBTWriter::BeginCompound(const AString & a_Name)
|
||||
ASSERT(!"Stack overflow");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
TagCommon(a_Name, TAG_Compound);
|
||||
|
||||
|
||||
++m_CurrentStack;
|
||||
m_Stack[m_CurrentStack].m_Type = TAG_Compound;
|
||||
}
|
||||
@@ -378,7 +378,7 @@ void cFastNBTWriter::EndCompound(void)
|
||||
{
|
||||
ASSERT(m_CurrentStack > 0);
|
||||
ASSERT(IsStackTopCompound());
|
||||
|
||||
|
||||
m_Result.push_back(TAG_End);
|
||||
--m_CurrentStack;
|
||||
}
|
||||
@@ -394,12 +394,12 @@ void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType)
|
||||
ASSERT(!"Stack overflow");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
TagCommon(a_Name, TAG_List);
|
||||
|
||||
|
||||
m_Result.push_back(static_cast<char>(a_ChildrenType));
|
||||
m_Result.append(4, static_cast<char>(0));
|
||||
|
||||
|
||||
++m_CurrentStack;
|
||||
m_Stack[m_CurrentStack].m_Type = TAG_List;
|
||||
m_Stack[m_CurrentStack].m_Pos = static_cast<int>(m_Result.size()) - 4;
|
||||
@@ -415,7 +415,7 @@ void cFastNBTWriter::EndList(void)
|
||||
{
|
||||
ASSERT(m_CurrentStack > 0);
|
||||
ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List);
|
||||
|
||||
|
||||
// Update the list count:
|
||||
SetBEInt(const_cast<char *>(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count);
|
||||
|
||||
|
||||
+35
-35
@@ -56,16 +56,16 @@ Structure (all with the tree structure it describes) supports moving in memory (
|
||||
struct cFastNBTTag
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
eTagType m_Type;
|
||||
|
||||
|
||||
// The following members are indices into the data stream. m_DataLength == 0 if no data available
|
||||
// They must not be pointers, because the datastream may be copied into another AString object in the meantime.
|
||||
size_t m_NameStart;
|
||||
size_t m_NameLength;
|
||||
size_t m_DataStart;
|
||||
size_t m_DataLength;
|
||||
|
||||
|
||||
// The following members are indices into the array returned; -1 if not valid
|
||||
// They must not be pointers, because pointers would not survive std::vector reallocation
|
||||
int m_Parent;
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
int m_NextSibling;
|
||||
int m_FirstChild;
|
||||
int m_LastChild;
|
||||
|
||||
|
||||
cFastNBTTag(eTagType a_Type, int a_Parent) :
|
||||
m_Type(a_Type),
|
||||
m_NameStart(0),
|
||||
@@ -119,24 +119,24 @@ class cParsedNBT
|
||||
{
|
||||
public:
|
||||
cParsedNBT(const char * a_Data, size_t a_Length);
|
||||
|
||||
|
||||
bool IsValid(void) const {return m_IsValid; }
|
||||
|
||||
|
||||
/** Returns the root tag of the hierarchy. */
|
||||
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[static_cast<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[static_cast<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[static_cast<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[static_cast<size_t>(a_Tag)].m_PrevSibling; }
|
||||
|
||||
|
||||
/** Returns the length of the tag's data, in bytes.
|
||||
Not valid for Compound or List tags! */
|
||||
size_t GetDataLength (int a_Tag) const
|
||||
@@ -154,35 +154,35 @@ public:
|
||||
ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type != TAG_Compound);
|
||||
return m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_DataStart;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the direct child tag of the specified name, or -1 if no such tag. */
|
||||
int FindChildByName(int a_Tag, const AString & a_Name) const
|
||||
{
|
||||
return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length());
|
||||
}
|
||||
|
||||
|
||||
/** Returns the direct child tag of the specified name, or -1 if no such tag. */
|
||||
int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const;
|
||||
|
||||
/** 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[static_cast<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[static_cast<size_t>(a_Tag)].m_Type == TAG_List);
|
||||
return (m_Tags[static_cast<size_t>(a_Tag)].m_FirstChild < 0) ? TAG_End : m_Tags[static_cast<size_t>(m_Tags[static_cast<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[static_cast<size_t>(a_Tag)].m_Type == TAG_Byte);
|
||||
return static_cast<unsigned char>(m_Data[static_cast<size_t>(m_Tags[static_cast<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
|
||||
{
|
||||
@@ -208,20 +208,20 @@ public:
|
||||
inline float GetFloat(int a_Tag) const
|
||||
{
|
||||
ASSERT(m_Tags[static_cast<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
|
||||
char Check1[5 - sizeof(float)]; // Fails if sizeof(float) > 4
|
||||
char Check2[sizeof(float) - 3]; // Fails if sizeof(float) < 4
|
||||
UNUSED_VAR(Check1);
|
||||
UNUSED_VAR(Check2);
|
||||
|
||||
|
||||
Int32 i = GetBEInt(m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_DataStart);
|
||||
float f;
|
||||
memcpy(&f, &i, sizeof(f));
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the value stored in a Double tag. Not valid for any other tag type. */
|
||||
inline double GetDouble(int a_Tag) const
|
||||
{
|
||||
@@ -235,7 +235,7 @@ public:
|
||||
ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_Double);
|
||||
return NetworkToHostDouble8(m_Data + m_Tags[static_cast<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
|
||||
{
|
||||
@@ -244,7 +244,7 @@ public:
|
||||
res.assign(m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_DataStart, static_cast<size_t>(m_Tags[static_cast<size_t>(a_Tag)].m_DataLength));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the tag's name. For tags that are not named, returns an empty string. */
|
||||
inline AString GetName(int a_Tag) const
|
||||
{
|
||||
@@ -252,7 +252,7 @@ public:
|
||||
res.assign(m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_NameStart, static_cast<size_t>(m_Tags[static_cast<size_t>(a_Tag)].m_NameLength));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
const char * m_Data;
|
||||
size_t m_Length;
|
||||
@@ -277,13 +277,13 @@ class cFastNBTWriter
|
||||
{
|
||||
public:
|
||||
cFastNBTWriter(const AString & a_RootTagName = "");
|
||||
|
||||
|
||||
void BeginCompound(const AString & a_Name);
|
||||
void EndCompound(void);
|
||||
|
||||
|
||||
void BeginList(const AString & a_Name, eTagType a_ChildrenType);
|
||||
void EndList(void);
|
||||
|
||||
|
||||
void AddByte (const AString & a_Name, unsigned char a_Value);
|
||||
void AddShort (const AString & a_Name, Int16 a_Value);
|
||||
void AddInt (const AString & a_Name, Int32 a_Value);
|
||||
@@ -298,11 +298,11 @@ public:
|
||||
{
|
||||
AddByteArray(a_Name, a_Value.data(), a_Value.size());
|
||||
}
|
||||
|
||||
|
||||
const AString & GetResult(void) const {return m_Result; }
|
||||
|
||||
|
||||
void Finish(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
struct sParent
|
||||
@@ -312,24 +312,24 @@ protected:
|
||||
int m_Count; // for TAG_List, the element count
|
||||
eTagType m_ItemType; // for TAG_List, the element type
|
||||
} ;
|
||||
|
||||
|
||||
static const int MAX_STACK = 50; // Highly doubtful that an NBT would be constructed this many levels deep
|
||||
|
||||
|
||||
// These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed.
|
||||
sParent m_Stack[MAX_STACK];
|
||||
int m_CurrentStack;
|
||||
|
||||
|
||||
AString m_Result;
|
||||
|
||||
|
||||
bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); }
|
||||
|
||||
|
||||
void WriteString(const char * a_Data, UInt16 a_Length);
|
||||
|
||||
|
||||
inline void TagCommon(const AString & a_Name, eTagType a_Type)
|
||||
{
|
||||
// If we're directly inside a list, check that the list is of the correct type:
|
||||
ASSERT((m_Stack[m_CurrentStack].m_Type != TAG_List) || (m_Stack[m_CurrentStack].m_ItemType == a_Type));
|
||||
|
||||
|
||||
if (IsStackTopCompound())
|
||||
{
|
||||
// Compound: add the type and name:
|
||||
|
||||
@@ -68,7 +68,7 @@ bool cMapSerializer::Save(void)
|
||||
SaveMapToNBT(Writer);
|
||||
|
||||
Writer.Finish();
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size());
|
||||
ASSERT(TestParse.IsValid());
|
||||
@@ -140,7 +140,7 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT)
|
||||
if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Byte))
|
||||
{
|
||||
eDimension Dimension = static_cast<eDimension>(a_NBT.GetByte(CurrLine));
|
||||
|
||||
|
||||
if (Dimension != m_Map->m_World->GetDimension())
|
||||
{
|
||||
// TODO 2014-03-20 xdot: We should store nether maps in nether worlds, e.t.c.
|
||||
@@ -259,7 +259,7 @@ bool cIDCountSerializer::Save(void)
|
||||
}
|
||||
|
||||
Writer.Finish();
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size());
|
||||
ASSERT(TestParse.IsValid());
|
||||
|
||||
@@ -65,7 +65,7 @@ void cNBTChunkSerializer::Finish(void)
|
||||
{
|
||||
m_Writer.EndList();
|
||||
}
|
||||
|
||||
|
||||
// If light not valid, reset it to all zeroes:
|
||||
if (!m_IsLightValid)
|
||||
{
|
||||
@@ -100,7 +100,7 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin
|
||||
{
|
||||
m_Writer.AddByte ("Slot", static_cast<unsigned char>(a_Slot));
|
||||
}
|
||||
|
||||
|
||||
// Write the tag compound (for enchantment, firework, custom name and repair cost):
|
||||
if (
|
||||
(!a_Item.m_Enchantments.IsEmpty()) ||
|
||||
@@ -142,7 +142,7 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin
|
||||
}
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
@@ -457,7 +457,7 @@ void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock)
|
||||
void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
|
||||
|
||||
switch (a_Minecart->GetPayload())
|
||||
{
|
||||
case cMinecart::mpChest:
|
||||
@@ -490,7 +490,7 @@ void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart)
|
||||
break;
|
||||
}
|
||||
} // switch (Payload)
|
||||
|
||||
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
@@ -717,7 +717,7 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName());
|
||||
m_Writer.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0);
|
||||
|
||||
|
||||
switch (a_Projectile->GetProjectileKind())
|
||||
{
|
||||
case cProjectileEntity::pkArrow:
|
||||
@@ -734,7 +734,7 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
|
||||
case cProjectileEntity::pkSplashPotion:
|
||||
{
|
||||
cSplashPotionEntity * Potion = reinterpret_cast<cSplashPotionEntity *>(a_Projectile);
|
||||
|
||||
|
||||
m_Writer.AddInt("EffectType", static_cast<Int16>(Potion->GetEntityEffectType()));
|
||||
m_Writer.AddInt("EffectDuration", static_cast<Int16>(Potion->GetEntityEffect().GetDuration()));
|
||||
m_Writer.AddShort("EffectIntensity", Potion->GetEntityEffect().GetIntensity());
|
||||
@@ -920,7 +920,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity)
|
||||
}
|
||||
m_IsTagOpen = true;
|
||||
m_HasHadEntity = true;
|
||||
|
||||
|
||||
switch (a_Entity->GetEntityType())
|
||||
{
|
||||
case cEntity::etBoat: AddBoatEntity (reinterpret_cast<cBoat *> (a_Entity)); break;
|
||||
|
||||
@@ -70,19 +70,19 @@ public:
|
||||
|
||||
/** Close NBT tags that we've opened */
|
||||
void Finish(void);
|
||||
|
||||
|
||||
bool IsLightValid(void) const {return m_IsLightValid; }
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/* From cChunkDataSeparateCollector we inherit:
|
||||
- m_BlockTypes[]
|
||||
- m_BlockMetas[]
|
||||
- m_BlockLight[]
|
||||
- m_BlockSkyLight[] */
|
||||
|
||||
|
||||
cFastNBTWriter & m_Writer;
|
||||
|
||||
|
||||
bool m_IsTagOpen; // True if a tag has been opened in the callbacks and not yet closed.
|
||||
bool m_HasHadEntity; // True if any Entity has already been received and processed
|
||||
bool m_HasHadBlockEntity; // True if any BlockEntity has already been received and processed
|
||||
@@ -91,10 +91,10 @@ protected:
|
||||
|
||||
/** Writes an item into the writer, if slot >= 0, adds the Slot tag. The compound is named as requested. */
|
||||
void AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName = "");
|
||||
|
||||
|
||||
/** Writes an item grid into the writer; begins the stored slot numbers with a_BeginSlotNum. Note that it doesn't begin nor end the list tag */
|
||||
void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0);
|
||||
|
||||
|
||||
// Block entities:
|
||||
void AddBasicTileEntity (cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
||||
void AddBeaconEntity (cBeaconEntity * a_Entity);
|
||||
@@ -111,7 +111,7 @@ protected:
|
||||
void AddMobHeadEntity (cMobHeadEntity * a_MobHead);
|
||||
void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock);
|
||||
void AddFlowerPotEntity (cFlowerPotEntity * a_FlowerPot);
|
||||
|
||||
|
||||
// Entities:
|
||||
void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName);
|
||||
void AddBoatEntity (cBoat * a_Boat);
|
||||
@@ -126,9 +126,9 @@ protected:
|
||||
void AddExpOrbEntity (cExpOrb * a_ExpOrb);
|
||||
void AddItemFrameEntity (cItemFrame * a_ItemFrame);
|
||||
void AddPaintingEntity (cPainting * a_Painting);
|
||||
|
||||
|
||||
void AddMinecartChestContents(cMinecartWithChest * a_Minecart);
|
||||
|
||||
|
||||
// cChunkDataSeparateCollector overrides:
|
||||
virtual void LightIsValid(bool a_IsLightValid) override;
|
||||
virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) override;
|
||||
|
||||
@@ -70,7 +70,7 @@ bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, c
|
||||
return false;
|
||||
}
|
||||
File.Close();
|
||||
|
||||
|
||||
// Parse the NBT:
|
||||
cParsedNBT NBT(Contents.data(), Contents.size());
|
||||
if (!NBT.IsValid())
|
||||
@@ -78,7 +78,7 @@ bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, c
|
||||
LOG("Cannot parse the NBT in the schematic file \"%s\".", a_FileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return LoadFromSchematicNBT(a_BlockArea, NBT);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ bool cSchematicFileSerializer::LoadFromSchematicString(cBlockArea & a_BlockArea,
|
||||
LOG("%s: Cannot parse the NBT in the schematic data.", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return LoadFromSchematicNBT(a_BlockArea, NBT);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ bool cSchematicFileSerializer::SaveToSchematicFile(const cBlockArea & a_BlockAre
|
||||
LOG("%s: Cannot serialize the area into an NBT representation for file \"%s\".", __FUNCTION__, a_FileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Save to file
|
||||
cGZipFile File;
|
||||
if (!File.Open(a_FileName, cGZipFile::fmWrite))
|
||||
@@ -151,7 +151,7 @@ bool cSchematicFileSerializer::SaveToSchematicString(const cBlockArea & a_BlockA
|
||||
LOG("%s: Cannot serialize the area into an NBT representation.", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Gzip the data:
|
||||
int res = CompressStringGZIP(NBT.data(), NBT.size(), a_Out);
|
||||
if (res != Z_OK)
|
||||
@@ -196,7 +196,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int SizeX = a_NBT.GetShort(TSizeX);
|
||||
int SizeY = a_NBT.GetShort(TSizeY);
|
||||
int SizeZ = a_NBT.GetShort(TSizeZ);
|
||||
@@ -205,7 +205,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
|
||||
LOG("Dimensions are invalid in the schematic file: %d, %d, %d", SizeX, SizeY, SizeZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int TBlockTypes = a_NBT.FindChildByName(a_NBT.GetRoot(), "Blocks");
|
||||
int TBlockMetas = a_NBT.FindChildByName(a_NBT.GetRoot(), "Data");
|
||||
if ((TBlockTypes < 0) || (a_NBT.GetType(TBlockTypes) != TAG_ByteArray))
|
||||
@@ -214,14 +214,14 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
|
||||
return false;
|
||||
}
|
||||
bool AreMetasPresent = (TBlockMetas > 0) && (a_NBT.GetType(TBlockMetas) == TAG_ByteArray);
|
||||
|
||||
|
||||
a_BlockArea.Clear();
|
||||
a_BlockArea.SetSize(SizeX, SizeY, SizeZ, AreMetasPresent ? (cBlockArea::baTypes | cBlockArea::baMetas) : cBlockArea::baTypes);
|
||||
|
||||
|
||||
int TOffsetX = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetX");
|
||||
int TOffsetY = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetY");
|
||||
int TOffsetZ = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetZ");
|
||||
|
||||
|
||||
if (
|
||||
(TOffsetX < 0) || (TOffsetY < 0) || (TOffsetZ < 0) ||
|
||||
(a_NBT.GetType(TOffsetX) != TAG_Int) ||
|
||||
@@ -247,7 +247,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
|
||||
NumTypeBytes = a_NBT.GetDataLength(TBlockTypes);
|
||||
}
|
||||
memcpy(a_BlockArea.m_BlockTypes, a_NBT.GetData(TBlockTypes), NumTypeBytes);
|
||||
|
||||
|
||||
if (AreMetasPresent)
|
||||
{
|
||||
size_t NumMetaBytes = a_BlockArea.GetBlockCount();
|
||||
@@ -260,7 +260,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
|
||||
}
|
||||
memcpy(a_BlockArea.m_BlockMetas, a_NBT.GetData(TBlockMetas), NumMetaBytes);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA
|
||||
AString Dummy(a_BlockArea.GetBlockCount(), 0);
|
||||
Writer.AddByteArray("Data", Dummy.data(), Dummy.size());
|
||||
}
|
||||
|
||||
|
||||
Writer.AddInt("WEOffsetX", a_BlockArea.m_WEOffset.x);
|
||||
Writer.AddInt("WEOffsetY", a_BlockArea.m_WEOffset.y);
|
||||
Writer.AddInt("WEOffsetZ", a_BlockArea.m_WEOffset.z);
|
||||
@@ -304,7 +304,7 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA
|
||||
Writer.BeginList("TileEntities", TAG_Compound);
|
||||
Writer.EndList();
|
||||
Writer.Finish();
|
||||
|
||||
|
||||
return Writer.GetResult();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,20 +25,20 @@ class cParsedNBT;
|
||||
class cSchematicFileSerializer
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
/** Loads an area from a .schematic file. Returns true if successful. */
|
||||
static bool LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName);
|
||||
|
||||
|
||||
/** Loads an area from a string containing the .schematic file data. Returns true if successful. */
|
||||
static bool LoadFromSchematicString(cBlockArea & a_BlockArea, const AString & a_SchematicData);
|
||||
|
||||
|
||||
/** Saves the area into a .schematic file. Returns true if successful. */
|
||||
static bool SaveToSchematicFile(const cBlockArea & a_BlockArea, const AString & a_FileName);
|
||||
|
||||
|
||||
/** Saves the area into a string containing the .schematic file data.
|
||||
Returns true if successful, false on failure. The data is stored into a_Out. */
|
||||
static bool SaveToSchematicString(const cBlockArea & a_BlockArea, AString & a_Out);
|
||||
|
||||
|
||||
private:
|
||||
/** Loads the area from a schematic file uncompressed and parsed into a NBT tree.
|
||||
Returns true if successful. */
|
||||
|
||||
@@ -67,7 +67,7 @@ bool cScoreboardSerializer::Save(void)
|
||||
SaveScoreboardToNBT(Writer);
|
||||
|
||||
Writer.Finish();
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size());
|
||||
ASSERT(TestParse.IsValid());
|
||||
@@ -102,7 +102,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
||||
a_Writer.BeginCompound("data");
|
||||
|
||||
a_Writer.BeginList("Objectives", TAG_Compound);
|
||||
|
||||
|
||||
for (cScoreboard::cObjectiveMap::const_iterator it = m_ScoreBoard->m_Objectives.begin(); it != m_ScoreBoard->m_Objectives.end(); ++it)
|
||||
{
|
||||
const cObjective & Objective = it->second;
|
||||
@@ -133,7 +133,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
||||
|
||||
a_Writer.AddString("Name", it2->first);
|
||||
a_Writer.AddString("Objective", it->first);
|
||||
|
||||
|
||||
a_Writer.EndCompound();
|
||||
}
|
||||
}
|
||||
@@ -141,7 +141,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
||||
a_Writer.EndList(); // PlayerScores
|
||||
|
||||
a_Writer.BeginList("Teams", TAG_Compound);
|
||||
|
||||
|
||||
for (cScoreboard::cTeamMap::const_iterator it = m_ScoreBoard->m_Teams.begin(); it != m_ScoreBoard->m_Teams.end(); ++it)
|
||||
{
|
||||
const cTeam & Team = it->second;
|
||||
|
||||
+120
-120
@@ -110,7 +110,7 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) :
|
||||
Writer.AddString("LevelName", a_World->GetName());
|
||||
Writer.EndCompound();
|
||||
Writer.Finish();
|
||||
|
||||
|
||||
gzFile gz = gzopen((FILE_IO_PREFIX + fnam).c_str(), "wb");
|
||||
if (gz != nullptr)
|
||||
{
|
||||
@@ -145,7 +145,7 @@ bool cWSSAnvil::LoadChunk(const cChunkCoords & a_Chunk)
|
||||
// The reason for failure is already printed in GetChunkData()
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return LoadChunkFromData(a_Chunk, ChunkData);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ bool cWSSAnvil::SaveChunk(const cChunkCoords & a_Chunk)
|
||||
LOGWARNING("Cannot store chunk [%d, %d] data", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Everything successful
|
||||
return true;
|
||||
}
|
||||
@@ -266,7 +266,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk)
|
||||
ASSERT(a_Chunk.m_ChunkZ - RegionZ * 32 >= 0);
|
||||
ASSERT(a_Chunk.m_ChunkX - RegionX * 32 < 32);
|
||||
ASSERT(a_Chunk.m_ChunkZ - RegionZ * 32 < 32);
|
||||
|
||||
|
||||
// Is it already cached?
|
||||
for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr)
|
||||
{
|
||||
@@ -282,7 +282,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk)
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load it anew:
|
||||
AString FileName;
|
||||
Printf(FileName, "%s%cregion", m_World->GetName().c_str(), cFile::PathSeparator);
|
||||
@@ -294,7 +294,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk)
|
||||
return nullptr;
|
||||
}
|
||||
m_Files.push_front(f);
|
||||
|
||||
|
||||
// If there are too many MCA files cached, delete the last one used:
|
||||
if (m_Files.size() > MAX_MCA_FILES)
|
||||
{
|
||||
@@ -319,7 +319,7 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString &
|
||||
ChunkLoadFailed(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, "InflateString() failed", a_Data);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Parse the NBT data:
|
||||
cParsedNBT NBT(Uncompressed.data(), Uncompressed.size());
|
||||
if (!NBT.IsValid())
|
||||
@@ -346,7 +346,7 @@ bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data)
|
||||
return false;
|
||||
}
|
||||
Writer.Finish();
|
||||
|
||||
|
||||
CompressString(Writer.GetResult().data(), Writer.GetResult().size(), a_Data, m_CompressionFactor);
|
||||
return true;
|
||||
}
|
||||
@@ -362,12 +362,12 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
||||
cChunkDef::BlockNibbles MetaData;
|
||||
cChunkDef::BlockNibbles BlockLight;
|
||||
cChunkDef::BlockNibbles SkyLight;
|
||||
|
||||
|
||||
memset(BlockTypes, E_BLOCK_AIR, sizeof(BlockTypes));
|
||||
memset(MetaData, 0, sizeof(MetaData));
|
||||
memset(SkyLight, 0xff, sizeof(SkyLight)); // By default, data not present in the NBT means air, which means full skylight
|
||||
memset(BlockLight, 0x00, sizeof(BlockLight));
|
||||
|
||||
|
||||
// Load the blockdata, blocklight and skylight:
|
||||
int Level = a_NBT.FindChildByName(0, "Level");
|
||||
if (Level < 0)
|
||||
@@ -405,7 +405,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
||||
CopyNBTData(a_NBT, Child, "SkyLight", reinterpret_cast<char *>(&(SkyLight[y * 2048])), 2048);
|
||||
CopyNBTData(a_NBT, Child, "BlockLight", reinterpret_cast<char *>(&(BlockLight[y * 2048])), 2048);
|
||||
} // for itr - LevelSections[]
|
||||
|
||||
|
||||
// Load the biomes from NBT, if present and valid. First try MCS-style, then Vanilla-style:
|
||||
cChunkDef::BiomeMap BiomeMap;
|
||||
cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "MCSBiomes"));
|
||||
@@ -414,15 +414,15 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
||||
// MCS-style biomes not available, load vanilla-style:
|
||||
Biomes = LoadVanillaBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes"));
|
||||
}
|
||||
|
||||
|
||||
// Load the entities from NBT:
|
||||
cEntityList Entities;
|
||||
cBlockEntityList BlockEntities;
|
||||
LoadEntitiesFromNBT (Entities, a_NBT, a_NBT.FindChildByName(Level, "Entities"));
|
||||
LoadBlockEntitiesFromNBT(BlockEntities, a_NBT, a_NBT.FindChildByName(Level, "TileEntities"), BlockTypes, MetaData);
|
||||
|
||||
|
||||
bool IsLightValid = (a_NBT.FindChildByName(Level, "MCSIsLightValid") > 0);
|
||||
|
||||
|
||||
/*
|
||||
// Uncomment this block for really cool stuff :)
|
||||
// DEBUG magic: Invert the underground, so that we can see the MC generator in action :)
|
||||
@@ -458,7 +458,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
||||
}
|
||||
} // for y
|
||||
//*/
|
||||
|
||||
|
||||
cSetChunkDataPtr SetChunkData(new cSetChunkData(
|
||||
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
|
||||
BlockTypes, MetaData,
|
||||
@@ -501,7 +501,7 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
|
||||
return false;
|
||||
}
|
||||
Serializer.Finish(); // Close NBT tags
|
||||
|
||||
|
||||
// Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray):
|
||||
if (Serializer.m_BiomesAreValid)
|
||||
{
|
||||
@@ -535,7 +535,7 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
|
||||
a_Writer.EndCompound();
|
||||
}
|
||||
a_Writer.EndList(); // "Sections"
|
||||
|
||||
|
||||
// Store the information that the lighting is valid.
|
||||
// For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading.
|
||||
if (Serializer.IsLightValid())
|
||||
@@ -545,10 +545,10 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
|
||||
|
||||
// Save the world age to the chunk data. Required by vanilla and mcedit.
|
||||
a_Writer.AddLong("LastUpdate", m_World->GetWorldAge());
|
||||
|
||||
|
||||
// Store the flag that the chunk has all the ores, trees, dungeons etc. MCS chunks are always complete.
|
||||
a_Writer.AddByte("TerrainPopulated", 1);
|
||||
|
||||
|
||||
a_Writer.EndCompound(); // "Level"
|
||||
return true;
|
||||
}
|
||||
@@ -619,7 +619,7 @@ void cWSSAnvil::LoadEntitiesFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child))
|
||||
{
|
||||
if (a_NBT.GetType(Child) != TAG_Compound)
|
||||
@@ -645,7 +645,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child))
|
||||
{
|
||||
if (a_NBT.GetType(Child) != TAG_Compound)
|
||||
@@ -761,19 +761,19 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
|
||||
a_Item.Empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int Damage = a_NBT.FindChildByName(a_TagIdx, "Damage");
|
||||
if ((Damage > 0) && (a_NBT.GetType(Damage) == TAG_Short))
|
||||
{
|
||||
a_Item.m_ItemDamage = a_NBT.GetShort(Damage);
|
||||
}
|
||||
|
||||
|
||||
int Count = a_NBT.FindChildByName(a_TagIdx, "Count");
|
||||
if ((Count > 0) && (a_NBT.GetType(Count) == TAG_Byte))
|
||||
{
|
||||
a_Item.m_ItemCount = static_cast<char>(a_NBT.GetByte(Count));
|
||||
}
|
||||
|
||||
|
||||
// Find the "tag" tag, used for enchantments and other extra data
|
||||
int TagTag = a_NBT.FindChildByName(a_TagIdx, "tag");
|
||||
if (TagTag <= 0)
|
||||
@@ -819,7 +819,7 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
|
||||
{
|
||||
cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, a_NBT, FireworksTag, static_cast<ENUM_ITEM_ID>(a_Item.m_ItemType));
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1134,7 +1134,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
{
|
||||
return nullptr; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<cFurnaceEntity> Furnace = cpp14::make_unique<cFurnaceEntity>(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World);
|
||||
Furnace->SetLoading(true);
|
||||
|
||||
@@ -1152,7 +1152,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
Furnace->SetSlot(a_NBT.GetByte(Slot), Item);
|
||||
}
|
||||
} // for itr - ItemDefs[]
|
||||
|
||||
|
||||
// Load burn time:
|
||||
int BurnTime = a_NBT.FindChildByName(a_TagIdx, "BurnTime");
|
||||
if (BurnTime >= 0)
|
||||
@@ -1161,7 +1161,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
// Anvil doesn't store the time that the fuel can burn. We simply "reset" the current value to be the 100%
|
||||
Furnace->SetBurnTimes(bt, 0);
|
||||
}
|
||||
|
||||
|
||||
// Load cook time:
|
||||
int CookTime = a_NBT.FindChildByName(a_TagIdx, "CookTime");
|
||||
if (CookTime >= 0)
|
||||
@@ -1741,9 +1741,9 @@ void cWSSAnvil::LoadMinecartFFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Load the Push and Fuel tags
|
||||
|
||||
|
||||
a_Entities.push_back(Minecart.release());
|
||||
}
|
||||
|
||||
@@ -1758,7 +1758,7 @@ void cWSSAnvil::LoadMinecartTFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Everything to do with TNT carts
|
||||
|
||||
a_Entities.push_back(Minecart.release());
|
||||
@@ -1775,7 +1775,7 @@ void cWSSAnvil::LoadMinecartHFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Everything to do with hopper carts
|
||||
|
||||
a_Entities.push_back(Minecart.release());
|
||||
@@ -1798,13 +1798,13 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<cPickup> Pickup = cpp14::make_unique<cPickup>(0, 0, 0, Item, false); // Pickup delay doesn't matter, just say false
|
||||
if (!LoadEntityBaseFromNBT(*Pickup.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Load age:
|
||||
int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (Age > 0)
|
||||
@@ -1826,14 +1826,14 @@ void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Load Fuse Ticks:
|
||||
int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse");
|
||||
if (FuseTicks > 0)
|
||||
{
|
||||
TNT->SetFuseTicks(static_cast<int>(a_NBT.GetByte(FuseTicks)));
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(TNT.release());
|
||||
}
|
||||
|
||||
@@ -1911,7 +1911,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<cItemFrame> ItemFrame = cpp14::make_unique<cItemFrame>(BLOCK_FACE_NONE, 0.0, 0.0, 0.0);
|
||||
if (!LoadEntityBaseFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
@@ -1920,14 +1920,14 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
ItemFrame->SetItem(Item);
|
||||
|
||||
LoadHangingFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx);
|
||||
|
||||
|
||||
// Load Rotation:
|
||||
int Rotation = a_NBT.FindChildByName(a_TagIdx, "ItemRotation");
|
||||
if (Rotation > 0)
|
||||
{
|
||||
ItemFrame->SetItemRotation(static_cast<Byte>(a_NBT.GetByte(Rotation)));
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(ItemFrame.release());
|
||||
}
|
||||
|
||||
@@ -1965,7 +1965,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Load pickup state:
|
||||
int PickupIdx = a_NBT.FindChildByName(a_TagIdx, "pickup");
|
||||
if ((PickupIdx > 0) && (a_NBT.GetType(PickupIdx) == TAG_Byte))
|
||||
@@ -1981,14 +1981,14 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
Arrow->SetPickupState((a_NBT.GetByte(PlayerIdx) == 0) ? cArrowEntity::psNoPickup : cArrowEntity::psInSurvivalOrCreative);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load damage:
|
||||
int DamageIdx = a_NBT.FindChildByName(a_TagIdx, "damage");
|
||||
if ((DamageIdx > 0) && (a_NBT.GetType(DamageIdx) == TAG_Double))
|
||||
{
|
||||
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");
|
||||
@@ -2020,7 +2020,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Store the new arrow in the entities list:
|
||||
a_Entities.push_back(Arrow.release());
|
||||
}
|
||||
@@ -2035,15 +2035,15 @@ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedN
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int EffectDuration = a_NBT.FindChildByName(a_TagIdx, "EffectDuration");
|
||||
int EffectIntensity = a_NBT.FindChildByName(a_TagIdx, "EffectIntensity");
|
||||
int EffectDistanceModifier = a_NBT.FindChildByName(a_TagIdx, "EffectDistanceModifier");
|
||||
|
||||
|
||||
SplashPotion->SetEntityEffectType(static_cast<cEntityEffect::eType>(a_NBT.FindChildByName(a_TagIdx, "EffectType")));
|
||||
SplashPotion->SetEntityEffect(cEntityEffect(EffectDuration, static_cast<Int16>(EffectIntensity), EffectDistanceModifier));
|
||||
SplashPotion->SetPotionColor(a_NBT.FindChildByName(a_TagIdx, "PotionName"));
|
||||
|
||||
|
||||
// Store the new splash potion in the entities list:
|
||||
a_Entities.push_back(SplashPotion.release());
|
||||
}
|
||||
@@ -2059,7 +2059,7 @@ void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Store the new snowball in the entities list:
|
||||
a_Entities.push_back(Snowball.release());
|
||||
}
|
||||
@@ -2075,7 +2075,7 @@ void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Store the new egg in the entities list:
|
||||
a_Entities.push_back(Egg.release());
|
||||
}
|
||||
@@ -2091,7 +2091,7 @@ void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Store the new fireball in the entities list:
|
||||
a_Entities.push_back(Fireball.release());
|
||||
}
|
||||
@@ -2107,7 +2107,7 @@ void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Store the new FireCharge in the entities list:
|
||||
a_Entities.push_back(FireCharge.release());
|
||||
}
|
||||
@@ -2123,7 +2123,7 @@ void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cPar
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Store the new enderpearl in the entities list:
|
||||
a_Entities.push_back(Enderpearl.release());
|
||||
}
|
||||
@@ -2139,7 +2139,7 @@ void cWSSAnvil::LoadBatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2159,7 +2159,7 @@ void cWSSAnvil::LoadBlazeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2179,7 +2179,7 @@ void cWSSAnvil::LoadCaveSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2199,7 +2199,7 @@ void cWSSAnvil::LoadChickenFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2219,7 +2219,7 @@ void cWSSAnvil::LoadCowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2239,7 +2239,7 @@ void cWSSAnvil::LoadCreeperFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2259,7 +2259,7 @@ void cWSSAnvil::LoadEnderDragonFromNBT(cEntityList & a_Entities, const cParsedNB
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2319,7 +2319,7 @@ void cWSSAnvil::LoadGiantFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2339,7 +2339,7 @@ void cWSSAnvil::LoadGuardianFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2372,12 +2372,12 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
@@ -2390,7 +2390,7 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -2405,7 +2405,7 @@ void cWSSAnvil::LoadIronGolemFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2434,7 +2434,7 @@ void cWSSAnvil::LoadMagmaCubeFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2454,7 +2454,7 @@ void cWSSAnvil::LoadMooshroomFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2474,7 +2474,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2492,7 +2492,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -2507,12 +2507,12 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
@@ -2525,7 +2525,7 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -2551,12 +2551,12 @@ void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
@@ -2569,7 +2569,7 @@ void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -2591,7 +2591,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2602,7 +2602,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
Monster->SetSheared(a_NBT.GetByte(ShearedIdx) != 0);
|
||||
}
|
||||
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
@@ -2615,7 +2615,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -2630,7 +2630,7 @@ void cWSSAnvil::LoadSilverfishFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2658,7 +2658,7 @@ void cWSSAnvil::LoadSkeletonFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2687,7 +2687,7 @@ void cWSSAnvil::LoadSlimeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2707,7 +2707,7 @@ void cWSSAnvil::LoadSnowGolemFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2727,7 +2727,7 @@ void cWSSAnvil::LoadSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2747,7 +2747,7 @@ void cWSSAnvil::LoadSquidFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2775,12 +2775,12 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
@@ -2793,8 +2793,8 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT &
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -2809,7 +2809,7 @@ void cWSSAnvil::LoadWitchFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2829,7 +2829,7 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@@ -2859,7 +2859,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LoadWolfOwner(*Monster.get(), a_NBT, a_TagIdx);
|
||||
|
||||
int SittingIdx = a_NBT.FindChildByName(a_TagIdx, "Sitting");
|
||||
@@ -2894,7 +2894,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
@@ -2907,7 +2907,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -2930,12 +2930,12 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
@@ -2948,7 +2948,7 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -2968,7 +2968,7 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
@@ -2981,7 +2981,7 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
|
||||
a_Entities.push_back(Monster.release());
|
||||
}
|
||||
|
||||
@@ -3008,7 +3008,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta
|
||||
// There is no owner, bail out:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Convert name to UUID, if needed:
|
||||
if (OwnerUUID.empty())
|
||||
{
|
||||
@@ -3026,7 +3026,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta
|
||||
// Normalize the UUID:
|
||||
OwnerUUID = cMojangAPI::MakeUUIDShort(OwnerUUID);
|
||||
}
|
||||
|
||||
|
||||
// Convert UUID to name, if needed:
|
||||
if (OwnerName.empty())
|
||||
{
|
||||
@@ -3038,7 +3038,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
a_Wolf.SetOwner(OwnerName, OwnerUUID);
|
||||
a_Wolf.SetIsTame(true);
|
||||
}
|
||||
@@ -3055,7 +3055,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
|
||||
return false;
|
||||
}
|
||||
a_Entity.SetPosition(Pos[0], Pos[1], Pos[2]);
|
||||
|
||||
|
||||
double Speed[3];
|
||||
if (!LoadDoublesListFromNBT(Speed, 3, a_NBT, a_NBT.FindChildByName(a_TagIdx, "Motion")))
|
||||
{
|
||||
@@ -3065,7 +3065,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
|
||||
Speed[2] = 0;
|
||||
}
|
||||
a_Entity.SetSpeed(Speed[0], Speed[1], Speed[2]);
|
||||
|
||||
|
||||
double Rotation[3];
|
||||
if (!LoadDoublesListFromNBT(Rotation, 2, a_NBT, a_NBT.FindChildByName(a_TagIdx, "Rotation")))
|
||||
{
|
||||
@@ -3079,7 +3079,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
|
||||
// Load health:
|
||||
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
|
||||
a_Entity.SetHealth(Health > 0 ? a_NBT.GetShort(Health) : a_Entity.GetMaxHealth());
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3133,7 +3133,7 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool IsInGround = false;
|
||||
int InGroundIdx = a_NBT.FindChildByName(a_TagIdx, "inGround");
|
||||
if (InGroundIdx > 0)
|
||||
@@ -3141,7 +3141,7 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP
|
||||
IsInGround = (a_NBT.GetByte(InGroundIdx) != 0);
|
||||
}
|
||||
a_Entity.SetIsInGround(IsInGround);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3230,13 +3230,13 @@ cWSSAnvil::cMCAFile::cMCAFile(cWSSAnvil & a_ParentSchema, const AString & a_File
|
||||
bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading)
|
||||
{
|
||||
bool writeOutNeeded = false;
|
||||
|
||||
|
||||
if (m_File.IsOpen())
|
||||
{
|
||||
// Already open
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (a_IsForReading)
|
||||
{
|
||||
if (!cFile::Exists(m_FileName))
|
||||
@@ -3245,13 +3245,13 @@ bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!m_File.Open(m_FileName, cFile::fmReadWrite))
|
||||
{
|
||||
// The file failed to open
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Load the header:
|
||||
if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header))
|
||||
{
|
||||
@@ -3269,7 +3269,7 @@ bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading)
|
||||
memset(m_TimeStamps, 0, sizeof(m_TimeStamps));
|
||||
writeOutNeeded = true;
|
||||
}
|
||||
|
||||
|
||||
if (writeOutNeeded)
|
||||
{
|
||||
m_File.Seek(0);
|
||||
@@ -3296,7 +3296,7 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int LocalX = a_Chunk.m_ChunkX % 32;
|
||||
if (LocalX < 0)
|
||||
{
|
||||
@@ -3313,9 +3313,9 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_File.Seek(static_cast<int>(ChunkOffset * 4096));
|
||||
|
||||
|
||||
UInt32 ChunkSize = 0;
|
||||
if (m_File.Read(&ChunkSize, 4) != 4)
|
||||
{
|
||||
@@ -3337,7 +3337,7 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a
|
||||
return false;
|
||||
}
|
||||
ChunkSize--;
|
||||
|
||||
|
||||
a_Data = m_File.Read(ChunkSize);
|
||||
if (a_Data.size() != ChunkSize)
|
||||
{
|
||||
@@ -3376,7 +3376,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri
|
||||
{
|
||||
LocalZ = 32 + LocalZ;
|
||||
}
|
||||
|
||||
|
||||
unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data);
|
||||
|
||||
// Store the chunk data:
|
||||
@@ -3398,7 +3398,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri
|
||||
LOGWARNING("Cannot save chunk [%d, %d], writing(3) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Add padding to 4K boundary:
|
||||
size_t BytesWritten = a_Data.size() + MCA_CHUNK_HEADER_LENGTH;
|
||||
if (BytesWritten % 4096 != 0)
|
||||
@@ -3406,7 +3406,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri
|
||||
static const char Padding[4095] = {0};
|
||||
m_File.Write(Padding, 4096 - (BytesWritten % 4096));
|
||||
}
|
||||
|
||||
|
||||
// Store the header:
|
||||
ChunkSize = (static_cast<u_long>(a_Data.size()) + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size up to nearest 4KB sector, make it a sector number
|
||||
if (ChunkSize > 255)
|
||||
@@ -3416,7 +3416,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Store the header info in the table
|
||||
m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize);
|
||||
|
||||
@@ -3438,7 +3438,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri
|
||||
LOGWARNING("Cannot save chunk [%d, %d], writing timestamps to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3455,7 +3455,7 @@ unsigned cWSSAnvil::cMCAFile::FindFreeLocation(int a_LocalX, int a_LocalZ, const
|
||||
{
|
||||
return ChunkLocation >> 8;
|
||||
}
|
||||
|
||||
|
||||
// Doesn't fit, append to the end of file (we're wasting a lot of space, TODO: fix this later)
|
||||
unsigned MaxLocation = 2 << 8; // Minimum sector is #2 - after the headers
|
||||
for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++)
|
||||
|
||||
+35
-35
@@ -31,10 +31,10 @@ enum
|
||||
{
|
||||
/** Maximum number of chunks in an MCA file - also the count of the header items */
|
||||
MCA_MAX_CHUNKS = 32 * 32,
|
||||
|
||||
|
||||
/** The MCA header is 8 KiB */
|
||||
MCA_HEADER_SIZE = MCA_MAX_CHUNKS * 8,
|
||||
|
||||
|
||||
/** There are 5 bytes of header in front of each chunk */
|
||||
MCA_CHUNK_HEADER_LENGTH = 5,
|
||||
} ;
|
||||
@@ -47,55 +47,55 @@ class cWSSAnvil :
|
||||
public cWSSchema
|
||||
{
|
||||
typedef cWSSchema super;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
cWSSAnvil(cWorld * a_World, int a_CompressionFactor);
|
||||
virtual ~cWSSAnvil();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
class cMCAFile
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
cMCAFile(cWSSAnvil & a_ParentSchema, const AString & a_FileName, int a_RegionX, int a_RegionZ);
|
||||
|
||||
|
||||
bool GetChunkData (const cChunkCoords & a_Chunk, AString & a_Data);
|
||||
bool SetChunkData (const cChunkCoords & a_Chunk, const AString & a_Data);
|
||||
bool EraseChunkData(const cChunkCoords & a_Chunk);
|
||||
|
||||
|
||||
int GetRegionX (void) const {return m_RegionX; }
|
||||
int GetRegionZ (void) const {return m_RegionZ; }
|
||||
const AString & GetFileName(void) const {return m_FileName; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
cWSSAnvil & m_ParentSchema;
|
||||
|
||||
|
||||
int m_RegionX;
|
||||
int m_RegionZ;
|
||||
cFile m_File;
|
||||
AString m_FileName;
|
||||
|
||||
|
||||
// The header, copied from the file so we don't have to seek to it all the time
|
||||
// First 1024 entries are chunk locations - the 3 + 1 byte sector-offset and sector-count
|
||||
unsigned m_Header[MCA_MAX_CHUNKS];
|
||||
|
||||
|
||||
// Chunk timestamps, following the chunk headers
|
||||
unsigned m_TimeStamps[MCA_MAX_CHUNKS];
|
||||
|
||||
|
||||
/** Finds a free location large enough to hold a_Data. Gets a hint of the chunk coords, places the data there if it fits. Returns the sector number. */
|
||||
unsigned FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data);
|
||||
|
||||
|
||||
/** Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creates new if not found) */
|
||||
bool OpenFile(bool a_IsForReading);
|
||||
} ;
|
||||
typedef std::list<cMCAFile *> cMCAFiles;
|
||||
|
||||
|
||||
cCriticalSection m_CS;
|
||||
cMCAFiles m_Files; // a MRU cache of MCA files
|
||||
|
||||
|
||||
int m_CompressionFactor;
|
||||
|
||||
|
||||
@@ -110,41 +110,41 @@ protected:
|
||||
|
||||
/** Loads the chunk from the data (no locking needed) */
|
||||
bool LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data);
|
||||
|
||||
|
||||
/** Saves the chunk into datastream (no locking needed) */
|
||||
bool SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data);
|
||||
|
||||
|
||||
/** Loads the chunk from NBT data (no locking needed).
|
||||
a_RawChunkData is the raw (compressed) chunk data, used for offloading when chunk loading fails. */
|
||||
bool LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT, const AString & a_RawChunkData);
|
||||
|
||||
|
||||
/** Saves the chunk into NBT data using a_Writer; returns true on success */
|
||||
bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer);
|
||||
|
||||
|
||||
/** Loads the chunk's biome map from vanilla-format; returns a_BiomeMap if biomes present and valid, nullptr otherwise */
|
||||
cChunkDef::BiomeMap * LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
|
||||
/** Loads the chunk's biome map from MCS format; returns a_BiomeMap if biomes present and valid, nullptr otherwise */
|
||||
cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
|
||||
/** Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1) */
|
||||
void LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_Tag);
|
||||
|
||||
|
||||
/** Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) */
|
||||
void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas);
|
||||
|
||||
|
||||
/** Loads the data for a block entity from the specified NBT tag.
|
||||
Returns the loaded block entity, or nullptr upon failure. */
|
||||
cBlockEntity * LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
|
||||
/** Loads a cItem contents from the specified NBT tag; returns true if successful. Doesn't load the Slot tag */
|
||||
bool LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
|
||||
/** Loads contentents of an Items[] list tag into a cItemGrid
|
||||
ItemGrid begins at the specified slot offset
|
||||
Slots outside the ItemGrid range are ignored */
|
||||
void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0);
|
||||
|
||||
|
||||
/** Returns true iff the "id" child tag inside the specified tag equals the specified expected type. */
|
||||
bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType);
|
||||
|
||||
@@ -162,9 +162,9 @@ protected:
|
||||
cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadNoteBlockFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadSignFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SignBlockType);
|
||||
|
||||
|
||||
void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t 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);
|
||||
@@ -220,19 +220,19 @@ protected:
|
||||
void LoadWolfFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
|
||||
/** Loads the wolf's owner information from the NBT into the specified wolf entity. */
|
||||
void LoadWolfOwner(cWolf & a_Wolf, 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);
|
||||
|
||||
|
||||
/** Loads monster common data from the NBT compound; returns true if successful */
|
||||
bool LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
|
||||
/** Loads projectile common data from the NBT compound; returns true if successful */
|
||||
bool LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIx);
|
||||
|
||||
|
||||
/** Loads an array of doubles of the specified length from the specified NBT list tag a_TagIdx; returns true if successful */
|
||||
bool LoadDoublesListFromNBT(double * a_Doubles, int a_NumDoubles, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
@@ -241,13 +241,13 @@ protected:
|
||||
|
||||
/** Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful */
|
||||
bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z);
|
||||
|
||||
|
||||
/** Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS is locked */
|
||||
cMCAFile * LoadMCAFile(const cChunkCoords & a_Chunk);
|
||||
|
||||
|
||||
/** Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer */
|
||||
void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, size_t a_Length);
|
||||
|
||||
|
||||
// cWSSchema overrides:
|
||||
virtual bool LoadChunk(const cChunkCoords & a_Chunk) override;
|
||||
virtual bool SaveChunk(const cChunkCoords & a_Chunk) override;
|
||||
|
||||
@@ -22,7 +22,7 @@ class cWSSForgetful :
|
||||
{
|
||||
public:
|
||||
cWSSForgetful(cWorld * a_World) : cWSSchema(a_World) {}
|
||||
|
||||
|
||||
protected:
|
||||
// cWSSchema overrides:
|
||||
virtual bool LoadChunk(const cChunkCoords & a_Chunk) override {return false; }
|
||||
@@ -65,7 +65,7 @@ bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName,
|
||||
m_World = a_World;
|
||||
m_StorageSchemaName = a_StorageSchemaName;
|
||||
InitSchemas(a_StorageCompressionFactor);
|
||||
|
||||
|
||||
return super::Start();
|
||||
}
|
||||
|
||||
@@ -85,14 +85,14 @@ void cWorldStorage::Stop(void)
|
||||
void cWorldStorage::WaitForFinish(void)
|
||||
{
|
||||
LOGD("Waiting for the world storage to finish saving");
|
||||
|
||||
|
||||
{
|
||||
m_LoadQueue.Clear();
|
||||
}
|
||||
|
||||
|
||||
// Wait for the saving to finish:
|
||||
WaitForSaveQueueEmpty();
|
||||
|
||||
|
||||
// Wait for the thread to finish:
|
||||
m_ShouldTerminate = true;
|
||||
m_Event.Set(); // Wake up the thread if waiting
|
||||
@@ -170,7 +170,7 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor)
|
||||
m_Schemas.push_back(new cWSSAnvil (m_World, a_StorageCompressionFactor));
|
||||
m_Schemas.push_back(new cWSSForgetful(m_World));
|
||||
// Add new schemas here
|
||||
|
||||
|
||||
if (NoCaseCompare(m_StorageSchemaName, "default") == 0)
|
||||
{
|
||||
m_SaveSchema = m_Schemas.front();
|
||||
@@ -184,7 +184,7 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor)
|
||||
return;
|
||||
}
|
||||
} // for itr - m_Schemas[]
|
||||
|
||||
|
||||
// Unknown schema selected, let the admin know:
|
||||
LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:",
|
||||
m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str()
|
||||
@@ -213,7 +213,7 @@ void cWorldStorage::Execute(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Success = LoadOneChunk();
|
||||
Success |= SaveOneChunk();
|
||||
} while (Success);
|
||||
@@ -258,7 +258,7 @@ bool cWorldStorage::SaveOneChunk(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Save the chunk, if it's valid:
|
||||
bool Status = false;
|
||||
if (m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ))
|
||||
@@ -286,7 +286,7 @@ bool cWorldStorage::SaveOneChunk(void)
|
||||
bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
ASSERT(m_World->IsChunkQueued(a_ChunkX, a_ChunkZ));
|
||||
|
||||
|
||||
cChunkCoords Coords(a_ChunkX, a_ChunkZ);
|
||||
|
||||
// First try the schema that is used for saving
|
||||
@@ -294,7 +294,7 @@ bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// If it didn't have the chunk, try all the other schemas:
|
||||
for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr)
|
||||
{
|
||||
@@ -303,10 +303,10 @@ bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Notify the chunk owner that the chunk failed to load (sets cChunk::m_HasLoadFailed to true):
|
||||
m_World->ChunkLoadFailed(a_ChunkX, a_ChunkZ);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,11 +37,11 @@ class cWSSchema abstract
|
||||
public:
|
||||
cWSSchema(cWorld * a_World) : m_World(a_World) {}
|
||||
virtual ~cWSSchema() {} // Force the descendants' destructors to be virtual
|
||||
|
||||
|
||||
virtual bool LoadChunk(const cChunkCoords & a_Chunk) = 0;
|
||||
virtual bool SaveChunk(const cChunkCoords & a_Chunk) = 0;
|
||||
virtual const AString GetName(void) const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
cWorld * m_World;
|
||||
@@ -58,7 +58,7 @@ class cWorldStorage :
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
cWorldStorage(void);
|
||||
@@ -71,16 +71,16 @@ public:
|
||||
/** Queues a chunk to be saved, asynchronously.
|
||||
The callback, if specified, will be called with the result of the save operation. */
|
||||
void QueueSaveChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = nullptr);
|
||||
|
||||
|
||||
bool Start(cWorld * a_World, const AString & a_StorageSchemaName, int a_StorageCompressionFactor); // Hide the cIsThread's Start() method, we need to provide args
|
||||
void Stop(void); // Hide the cIsThread's Stop() method, we need to signal the event
|
||||
void WaitForFinish(void);
|
||||
void WaitForLoadQueueEmpty(void);
|
||||
void WaitForSaveQueueEmpty(void);
|
||||
|
||||
|
||||
size_t GetLoadQueueLength(void);
|
||||
size_t GetSaveQueueLength(void);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
cWorld * m_World;
|
||||
@@ -88,27 +88,27 @@ protected:
|
||||
|
||||
cChunkCoordsQueue m_LoadQueue;
|
||||
cChunkCoordsQueue m_SaveQueue;
|
||||
|
||||
|
||||
/** All the storage schemas (all used for loading) */
|
||||
cWSSchemaList m_Schemas;
|
||||
|
||||
|
||||
/** The one storage schema used for saving */
|
||||
cWSSchema * m_SaveSchema;
|
||||
|
||||
/** Set when there's any addition to the queues */
|
||||
cEvent m_Event;
|
||||
|
||||
|
||||
|
||||
/** Loads the chunk specified; returns true on success, false on failure */
|
||||
bool LoadChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
void InitSchemas(int a_StorageCompressionFactor);
|
||||
|
||||
|
||||
virtual void Execute(void) override;
|
||||
|
||||
|
||||
/** Loads one chunk from the queue (if any queued); returns true if there are more chunks in the load queue */
|
||||
bool LoadOneChunk(void);
|
||||
|
||||
|
||||
/** Saves one chunk from the queue (if any queued); returns true if there are more chunks in the save queue */
|
||||
bool SaveOneChunk(void);
|
||||
} ;
|
||||
|
||||
Reference in New Issue
Block a user