Anvil storage: load block entities from both old and new name-styles. (#3784)
* WSSAnvil: Load the sign text from JSON, too.
This commit is contained in:
parent
fbe17a4e8a
commit
99b4c2bd09
@ -9,6 +9,7 @@
|
||||
#include "FastNBT.h"
|
||||
#include "EnchantmentSerializer.h"
|
||||
#include "zlib/zlib.h"
|
||||
#include "json/json.h"
|
||||
#include "../World.h"
|
||||
#include "../BlockID.h"
|
||||
#include "../Item.h"
|
||||
@ -858,7 +859,37 @@ void cWSSAnvil::LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a
|
||||
|
||||
|
||||
|
||||
bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
AString cWSSAnvil::DecodeSignLine(const AString & a_Line)
|
||||
{
|
||||
if (a_Line.empty())
|
||||
{
|
||||
return AString();
|
||||
}
|
||||
if (a_Line[0] != '{')
|
||||
{
|
||||
return a_Line;
|
||||
}
|
||||
|
||||
// Try to parse the JSON:
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
if (!reader.parse(a_Line, root, false) || !root.isObject())
|
||||
{
|
||||
return a_Line;
|
||||
}
|
||||
const auto & txt = root["text"];
|
||||
if (txt.isString())
|
||||
{
|
||||
return txt.asString();
|
||||
}
|
||||
return a_Line;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const AStringVector & a_ExpectedTypes, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the given tag is a compound:
|
||||
if (a_NBT.GetType(a_TagIdx) != TAG_Compound)
|
||||
@ -874,12 +905,24 @@ bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, con
|
||||
}
|
||||
|
||||
// Compare the value:
|
||||
if (strncmp(a_NBT.GetData(TagID), a_ExpectedType, static_cast<size_t>(a_NBT.GetDataLength(TagID))) == 0)
|
||||
for (const auto & et: a_ExpectedTypes)
|
||||
{
|
||||
return true;
|
||||
if (strncmp(a_NBT.GetData(TagID), et.c_str(), static_cast<size_t>(a_NBT.GetDataLength(TagID))) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
LOGWARNING("Block entity type mismatch: exp \"%s\", got \"%s\". The block entity at {%d, %d, %d} will lose all its properties.",
|
||||
a_ExpectedType,
|
||||
|
||||
// Expectation not met, output an error into the log:
|
||||
AString expectedTypes;
|
||||
for (const auto & et : a_ExpectedTypes)
|
||||
{
|
||||
expectedTypes.append(", \"");
|
||||
expectedTypes.append(et);
|
||||
expectedTypes.push_back('\"');
|
||||
}
|
||||
LOGWARNING("Block entity type mismatch: exp %s, got \"%s\". The block entity at {%d, %d, %d} will lose all its properties.",
|
||||
expectedTypes.c_str() + 2, // Skip the first ", " that is extra in the string
|
||||
AString(a_NBT.GetData(TagID), static_cast<size_t>(a_NBT.GetDataLength(TagID))).c_str(),
|
||||
a_BlockX, a_BlockY, a_BlockZ
|
||||
);
|
||||
@ -893,7 +936,8 @@ bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, con
|
||||
cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Beacon", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({"Beacon", "minecraft:beacon"});
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -935,7 +979,8 @@ cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagI
|
||||
cBlockEntity * cWSSAnvil::LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Brewingstand", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "Brewingstand", "minecraft:brewing_stand" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -993,23 +1038,11 @@ cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagId
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
// Note that older Cuberite code used "TrappedChest" for trapped chests; new code mimics vanilla and uses "Chest" throughout, but we allow migration here:
|
||||
if (a_NBT.GetType(a_TagIdx) != TAG_Compound)
|
||||
static const AStringVector expectedTypes({ "Chest", "TrappedChest", "minecraft:chest" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
int TagID = a_NBT.FindChildByName(a_TagIdx, "id");
|
||||
if ((TagID < 0) || (a_NBT.GetType(TagID) != TAG_String))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
auto BlockEntityType = a_NBT.GetString(TagID);
|
||||
if ((BlockEntityType != "Chest") && (BlockEntityType != "TrappedChest"))
|
||||
{
|
||||
LOGWARNING("Block entity type mismatch at {%d, %d, %d}: got \"%s\", expected \"Chest\". Chest contents will be lost.",
|
||||
a_BlockX, a_BlockY, a_BlockZ, BlockEntityType.c_str()
|
||||
);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
@ -1028,7 +1061,8 @@ cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagId
|
||||
cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Control", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "Control", "minecraft:command_block" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1065,7 +1099,8 @@ cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int
|
||||
cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Trap", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "Trap", "minecraft:dispenser" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1087,7 +1122,8 @@ cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_T
|
||||
cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Dropper", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "Dropper", "minecraft:dropper" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1109,7 +1145,8 @@ cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "FlowerPot", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "FlowerPot", "minecraft:flower_pot" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1147,7 +1184,8 @@ cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_T
|
||||
cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Furnace", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "Furnace", "minecraft:furnace" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1203,10 +1241,56 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
|
||||
|
||||
|
||||
cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
static const AStringVector expectedTypes({ "Hopper", "minecraft:hopper" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return nullptr; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this
|
||||
}
|
||||
auto Hopper = cpp14::make_unique<cHopperEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
|
||||
LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items);
|
||||
return Hopper.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
static const AStringVector expectedTypes({ "RecordPlayer", "minecraft:jukebox" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto Jukebox = cpp14::make_unique<cJukeboxEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
|
||||
int Record = a_NBT.FindChildByName(a_TagIdx, "Record");
|
||||
if (Record >= 0)
|
||||
{
|
||||
Jukebox->SetRecord(a_NBT.GetInt(Record));
|
||||
}
|
||||
return Jukebox.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "MobSpawner", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "MobSpawner", "minecraft:mob_spawner" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1251,53 +1335,11 @@ cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_
|
||||
|
||||
|
||||
|
||||
cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Hopper", a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||
{
|
||||
return nullptr; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this
|
||||
}
|
||||
auto Hopper = cpp14::make_unique<cHopperEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
|
||||
LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items);
|
||||
return Hopper.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "RecordPlayer", a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto Jukebox = cpp14::make_unique<cJukeboxEntity>(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, m_World);
|
||||
int Record = a_NBT.FindChildByName(a_TagIdx, "Record");
|
||||
if (Record >= 0)
|
||||
{
|
||||
Jukebox->SetRecord(a_NBT.GetInt(Record));
|
||||
}
|
||||
return Jukebox.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Skull", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "Skull", "minecraft:skull" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1369,7 +1411,8 @@ cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Music", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "Music", "minecraft:noteblock" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1390,7 +1433,8 @@ cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_T
|
||||
cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check if the data has a proper type:
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Sign", a_BlockX, a_BlockY, a_BlockZ))
|
||||
static const AStringVector expectedTypes({ "Sign", "minecraft:sign" });
|
||||
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_BlockX, a_BlockY, a_BlockZ))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -1400,25 +1444,25 @@ cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx
|
||||
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1");
|
||||
if (currentLine >= 0)
|
||||
{
|
||||
Sign->SetLine(0, a_NBT.GetString(currentLine));
|
||||
Sign->SetLine(0, DecodeSignLine(a_NBT.GetString(currentLine)));
|
||||
}
|
||||
|
||||
currentLine = a_NBT.FindChildByName(a_TagIdx, "Text2");
|
||||
if (currentLine >= 0)
|
||||
{
|
||||
Sign->SetLine(1, a_NBT.GetString(currentLine));
|
||||
Sign->SetLine(1, DecodeSignLine(a_NBT.GetString(currentLine)));
|
||||
}
|
||||
|
||||
currentLine = a_NBT.FindChildByName(a_TagIdx, "Text3");
|
||||
if (currentLine >= 0)
|
||||
{
|
||||
Sign->SetLine(2, a_NBT.GetString(currentLine));
|
||||
Sign->SetLine(2, DecodeSignLine(a_NBT.GetString(currentLine)));
|
||||
}
|
||||
|
||||
currentLine = a_NBT.FindChildByName(a_TagIdx, "Text4");
|
||||
if (currentLine >= 0)
|
||||
{
|
||||
Sign->SetLine(3, a_NBT.GetString(currentLine));
|
||||
Sign->SetLine(3, DecodeSignLine(a_NBT.GetString(currentLine)));
|
||||
}
|
||||
|
||||
return Sign.release();
|
||||
|
@ -145,10 +145,15 @@ protected:
|
||||
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.
|
||||
/** Decodes the text contained within a sign.
|
||||
Older versions used direct string representation, newer versions use JSON-formatted string.
|
||||
This function extracts the text from either version. */
|
||||
AString DecodeSignLine(const AString & a_Line);
|
||||
|
||||
/** Returns true iff the "id" child tag inside the specified tag equals (case-sensitive) any of the specified expected types.
|
||||
Logs a warning to the console on mismatch.
|
||||
The coordinates are used only for the log message. */
|
||||
bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const AStringVector & a_ExpectedTypes, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
cBlockEntity * LoadBeaconFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
@ -158,10 +163,10 @@ protected:
|
||||
cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadMobSpawnerFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadMobSpawnerFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadNoteBlockFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
cBlockEntity * LoadSignFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user