Merge branch 'master' into fixes
This commit is contained in:
commit
26b8471280
@ -44,6 +44,8 @@ ApplePlanks, 4 = AppleLog, *
|
|||||||
ConiferPlanks, 4 = ConiferLog, *
|
ConiferPlanks, 4 = ConiferLog, *
|
||||||
BirchPlanks, 4 = BirchLog, *
|
BirchPlanks, 4 = BirchLog, *
|
||||||
JunglePlanks, 4 = JungleLog, *
|
JunglePlanks, 4 = JungleLog, *
|
||||||
|
AcaciaPlanks, 4 = AcaciaLog, *
|
||||||
|
DarkOakPlanks, 4 = DarkOakLog, *
|
||||||
Stick, 4 = Planks, 2:2, 2:3
|
Stick, 4 = Planks, 2:2, 2:3
|
||||||
Torch, 4 = Stick, 1:2 | Coal, 1:1
|
Torch, 4 = Stick, 1:2 | Coal, 1:1
|
||||||
Workbench = Planks, 1:1, 1:2, 2:1, 2:2
|
Workbench = Planks, 1:1, 1:2, 2:1, 2:2
|
||||||
@ -74,11 +76,25 @@ PillarQuartzBlock = QuartzSlab, 1:1, 1:2
|
|||||||
ChiseledQuartzBlock, 2 = QuartzBlock, 1:1, 1:2
|
ChiseledQuartzBlock, 2 = QuartzBlock, 1:1, 1:2
|
||||||
CoalBlock = Coal, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
CoalBlock = Coal, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||||
HayBale = Wheat, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
HayBale = Wheat, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||||
|
SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
|
||||||
|
ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
|
||||||
|
BrickBlock = Brick, 1:1, 1:2, 2:1, 2:2
|
||||||
|
StoneBrick, 4 = Stone, 1:1, 1:2, 2:1, 2:2
|
||||||
|
BookShelf = Planks, 1:1, 2:1, 3:1, 1:3, 2:3, 3:3 | Book, 1:2, 2:2, 3:2
|
||||||
|
Sandstone, 4 = Sand, 1:1, 1:2, 2:1, 2:2
|
||||||
|
SmoothSandstone, 4 = Sandstone, 1:1, 1:2, 2:1, 2:2
|
||||||
|
OrnamentSandstone = SandstoneSlab, 1:1, 1:2
|
||||||
|
JackOLantern = Pumpkin, 1:1 | Torch, 1:2
|
||||||
|
|
||||||
# Slabs:
|
# Slabs:
|
||||||
StoneSlab, 6 = Stone, 1:1, 2:1, 3:1
|
StoneSlab, 6 = Stone, 1:1, 2:1, 3:1
|
||||||
SandstoneSlab, 6 = Sandstone, 1:1, 2:1, 3:1
|
SandstoneSlab, 6 = Sandstone, 1:1, 2:1, 3:1
|
||||||
WoodSlab, 6 = Planks, 1:1, 2:1, 3:1
|
SpruceWoodSlab, 6 = SprucePlanks, 1:1, 2:1, 3:1
|
||||||
|
BirchWoodSlab, 6 = BirchPlanks, 1:1, 2:1, 3:1
|
||||||
|
JungleWoodSlab, 6 = JunglePlanks, 1:1, 2:1, 3:1
|
||||||
|
AcaciaWoodSlab, 6 = AcaciaPlanks, 1:1, 2:1, 3:1
|
||||||
|
DarkOakWoodSlab, 6 = DarkOakPlanks, 1:1, 2:1, 3:1
|
||||||
|
OakWoodSlab, 6 = OakPlanks, 1:1, 2:1, 3:1
|
||||||
CobblestoneSlab, 6 = Cobblestone, 1:1, 2:1, 3:1
|
CobblestoneSlab, 6 = Cobblestone, 1:1, 2:1, 3:1
|
||||||
BrickSlab, 6 = BrickBlock, 1:1, 2:1, 3:1
|
BrickSlab, 6 = BrickBlock, 1:1, 2:1, 3:1
|
||||||
StonebrickSlab, 6 = StoneBrick, 1:1, 2:1, 3:1
|
StonebrickSlab, 6 = StoneBrick, 1:1, 2:1, 3:1
|
||||||
@ -86,9 +102,20 @@ NetherbrickSlab, 6 = NetherBrick, 1:1, 2:1, 3:1
|
|||||||
Quartzslab, 6 = QuartzBlock, 1:1, 2:1, 3:1
|
Quartzslab, 6 = QuartzBlock, 1:1, 2:1, 3:1
|
||||||
snow, 6 = SnowBlock, 1:1, 2:1, 3:1
|
snow, 6 = SnowBlock, 1:1, 2:1, 3:1
|
||||||
|
|
||||||
|
|
||||||
# Stairs:
|
# Stairs:
|
||||||
WoodStairs, 4 = Planks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
SpruceWoodStairs, 4 = SprucePlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
WoodStairs, 4 = Planks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
SpruceWoodStairs, 4 = SprucePlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
|
BirchWoodStairs, 4 = BirchPlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
|
BirchWoodStairs, 4 = BirchPlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
|
JungleWoodStairs, 4 = JunglePlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
|
JungleWoodStairs, 4 = JunglePlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
|
AcaciaWoodStairs, 4 = AcaciaPlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
|
AcaciaWoodStairs, 4 = AcaciaPlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
|
DarkOakWoodStairs, 4 = DarkOakPlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
|
DarkOakWoodStairs, 4 = DarkOakPlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
|
WoodStairs, 4 = OakPlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
|
WoodStairs, 4 = OakPlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
cobblestoneStairs, 4 = Cobblestone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
cobblestoneStairs, 4 = Cobblestone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
cobblestoneStairs, 4 = Cobblestone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
cobblestoneStairs, 4 = Cobblestone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
BrickStairs, 4 = BrickBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
BrickStairs, 4 = BrickBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
@ -101,15 +128,6 @@ quartzstairs, 4 = QuartzBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
|||||||
quartzstairs, 4 = QuartzBlock, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
quartzstairs, 4 = QuartzBlock, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
StoneBrickStairs, 4 = StoneBrick, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
StoneBrickStairs, 4 = StoneBrick, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||||
StoneBrickStairs, 4 = StoneBrick, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
StoneBrickStairs, 4 = StoneBrick, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||||
SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
|
|
||||||
ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
|
|
||||||
BrickBlock = Brick, 1:1, 1:2, 2:1, 2:2
|
|
||||||
StoneBrick, 4 = Stone, 1:1, 1:2, 2:1, 2:2
|
|
||||||
BookShelf = Planks, 1:1, 2:1, 3:1, 1:3, 2:3, 3:3 | Book, 1:2, 2:2, 3:2
|
|
||||||
Sandstone, 4 = Sand, 1:1, 1:2, 2:1, 2:2
|
|
||||||
SmoothSandstone, 4 = Sandstone, 1:1, 1:2, 2:1, 2:2
|
|
||||||
OrnamentSandstone = SandstoneSlab, 1:1, 1:2
|
|
||||||
JackOLantern = Pumpkin, 1:1 | Torch, 1:2
|
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
Carpet = Wool, 1:3, 2:3
|
Carpet = Wool, 1:3, 2:3
|
||||||
|
@ -17,6 +17,11 @@ birchplanks=5:2
|
|||||||
lightplanks=5:2
|
lightplanks=5:2
|
||||||
jungleplanks=5:3
|
jungleplanks=5:3
|
||||||
redplanks=5:3
|
redplanks=5:3
|
||||||
|
acaciaplanks=5:4
|
||||||
|
darkoakplanks=5:5
|
||||||
|
bigoakplanks=5:5
|
||||||
|
roofedoakplanks=5:5
|
||||||
|
|
||||||
|
|
||||||
; Obsolete: do not use "wood", as its meaning is not clear - wiki uses log as wood, we use planks as wood.
|
; Obsolete: do not use "wood", as its meaning is not clear - wiki uses log as wood, we use planks as wood.
|
||||||
wood=5
|
wood=5
|
||||||
@ -169,6 +174,7 @@ torch=50
|
|||||||
fire=51
|
fire=51
|
||||||
mobspawner=52
|
mobspawner=52
|
||||||
woodstairs=53
|
woodstairs=53
|
||||||
|
oakwoodstairs=53
|
||||||
chest=54
|
chest=54
|
||||||
redstonedust=55
|
redstonedust=55
|
||||||
redstonewire=55
|
redstonewire=55
|
||||||
@ -274,13 +280,47 @@ redstonelamp=123
|
|||||||
redstonelampoff=123
|
redstonelampoff=123
|
||||||
redstonelampon=124
|
redstonelampon=124
|
||||||
woodendoubleslab=125
|
woodendoubleslab=125
|
||||||
|
appledoublewoodslab=125:0
|
||||||
|
oakwooddoubleslab=125:0
|
||||||
|
coniferwooddoubleslab=125:1
|
||||||
|
pinewooddoubleslab=125:1
|
||||||
|
sprucewooddoubleslab=125:1
|
||||||
|
darkwooddoubleslab=125:1
|
||||||
|
birchwooddoubleslab=125:2
|
||||||
|
whitewooddoubleslab=125:2
|
||||||
|
junglewooddoubleslab=125:3
|
||||||
|
acaciawooddoubleslab=125:4
|
||||||
|
bigoakwooddoubleslab=125:5
|
||||||
|
darkoakwooddoubleslab=125:5
|
||||||
|
roofedwooddoubleslab=125:5
|
||||||
woodenslab=126
|
woodenslab=126
|
||||||
|
applewoodslab=126:0
|
||||||
|
oakwoodslab=126:0
|
||||||
|
coniferwoodslab=126:1
|
||||||
|
pinewoodslab=126:1
|
||||||
|
sprucewoodslab=126:1
|
||||||
|
darkwoodslab=126:1
|
||||||
|
birchwoodslab=126:2
|
||||||
|
whitewoodslab=126:2
|
||||||
|
junglewoodslab=126:3
|
||||||
|
acaciawoodslab=126:4
|
||||||
|
bigoakwoodslab=126:5
|
||||||
|
darkoakwoodslab=126:5
|
||||||
|
roofedwoodslab=126:5
|
||||||
|
cocoabeans=127
|
||||||
sandstonestairs=128
|
sandstonestairs=128
|
||||||
emeraldore=129
|
emeraldore=129
|
||||||
enderchest=130
|
enderchest=130
|
||||||
tripwirehook=131
|
tripwirehook=131
|
||||||
tripwire=132
|
tripwire=132
|
||||||
emeraldblock=133
|
emeraldblock=133
|
||||||
|
coniferwoodstairs=134
|
||||||
|
pinewoodstairs=134
|
||||||
|
sprucewoodstairs=134
|
||||||
|
darkwoodstairs=134
|
||||||
|
birchwoodstairs=135
|
||||||
|
whitewoodstairs=135
|
||||||
|
junglewoodstairs=136
|
||||||
commandblock=137
|
commandblock=137
|
||||||
beacon=138
|
beacon=138
|
||||||
cobblestonewall=139
|
cobblestonewall=139
|
||||||
@ -343,10 +383,18 @@ brownstainedglasspane=160:12
|
|||||||
greenstainedglasspane=160:13
|
greenstainedglasspane=160:13
|
||||||
redstainedglasspane=160:14
|
redstainedglasspane=160:14
|
||||||
blackstainedglasspane=160:15
|
blackstainedglasspane=160:15
|
||||||
acaciawood=162
|
acacialeaves=161
|
||||||
darkoakwood=162:1
|
bigoakleaves=161:1
|
||||||
acaciawoodenstairs=163
|
darkoakleaves=161:1
|
||||||
darkoakwoodenstairs=164
|
roofedoakleaves=161:1
|
||||||
|
acacialog=162
|
||||||
|
bigoaklog=162:1
|
||||||
|
darkoaklog=162:1
|
||||||
|
roofedoaklog=162:1
|
||||||
|
acaciawoodstairs=163
|
||||||
|
bigoakwoodstiars=164
|
||||||
|
darkoakwoodstairs=164
|
||||||
|
roofedoakwoodstairs=164
|
||||||
haybale=170
|
haybale=170
|
||||||
carpet=171
|
carpet=171
|
||||||
ironshovel=256
|
ironshovel=256
|
||||||
|
@ -297,6 +297,16 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
|
|||||||
m_BlockEntities.clear();
|
m_BlockEntities.clear();
|
||||||
std::swap(a_SetChunkData.GetBlockEntities(), m_BlockEntities);
|
std::swap(a_SetChunkData.GetBlockEntities(), m_BlockEntities);
|
||||||
|
|
||||||
|
// Check that all block entities have a valid blocktype at their respective coords (DEBUG-mode only):
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||||
|
{
|
||||||
|
BLOCKTYPE EntityBlockType = (*itr)->GetBlockType();
|
||||||
|
BLOCKTYPE WorldBlockType = GetBlock((*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ());
|
||||||
|
ASSERT(EntityBlockType == WorldBlockType);
|
||||||
|
} // for itr - m_BlockEntities
|
||||||
|
#endif // _DEBUG
|
||||||
|
|
||||||
// Set all block entities' World variable:
|
// Set all block entities' World variable:
|
||||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||||
{
|
{
|
||||||
|
@ -155,7 +155,7 @@ public:
|
|||||||
|
|
||||||
void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
|
void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
|
||||||
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const;
|
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const;
|
||||||
BLOCKTYPE GetBlock(Vector3i a_cords) const { return GetBlock(a_cords.x, a_cords.y, a_cords.z);}
|
BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); }
|
||||||
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
|
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
|
||||||
void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
|
void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
|
||||||
|
|
||||||
|
@ -891,31 +891,31 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta)
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Moving -X +Z
|
// Moving -X +Z
|
||||||
if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01)
|
if ((-GetSpeedX() * 0.4 / sqrt(2.0)) < 0.01)
|
||||||
{
|
{
|
||||||
// ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump!
|
// ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump!
|
||||||
AddSpeedX(-4 / sqrt(2));
|
AddSpeedX(-4 / sqrt(2.0));
|
||||||
AddSpeedZ(4 / sqrt(2));
|
AddSpeedZ(4 / sqrt(2.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit.
|
// ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit.
|
||||||
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2));
|
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0));
|
||||||
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2));
|
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01)
|
else if ((GetSpeedX() * 0.4 / sqrt(2.0)) < 0.01)
|
||||||
{
|
{
|
||||||
// Moving +X -Z
|
// Moving +X -Z
|
||||||
// ~ SpeedX <= 0 Immobile or not moving in the "right" direction
|
// ~ SpeedX <= 0 Immobile or not moving in the "right" direction
|
||||||
AddSpeedX(4 / sqrt(2));
|
AddSpeedX(4 / sqrt(2.0));
|
||||||
AddSpeedZ(-4 / sqrt(2));
|
AddSpeedZ(-4 / sqrt(2.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ~ SpeedX > 0 Moving in the "right" direction
|
// ~ SpeedX > 0 Moving in the "right" direction
|
||||||
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2));
|
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0));
|
||||||
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2));
|
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -943,28 +943,28 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta)
|
|||||||
if ((GetSpeedX() * 0.4) < 0.01)
|
if ((GetSpeedX() * 0.4) < 0.01)
|
||||||
{
|
{
|
||||||
// ~ SpeedX <= 0 Immobile or not moving in the "right" direction
|
// ~ SpeedX <= 0 Immobile or not moving in the "right" direction
|
||||||
AddSpeedX(4 / sqrt(2));
|
AddSpeedX(4 / sqrt(2.0));
|
||||||
AddSpeedZ(4 / sqrt(2));
|
AddSpeedZ(4 / sqrt(2.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ~ SpeedX > 0 Moving in the "right" direction
|
// ~ SpeedX > 0 Moving in the "right" direction
|
||||||
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2));
|
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0));
|
||||||
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2));
|
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((-GetSpeedX() * 0.4) < 0.01)
|
else if ((-GetSpeedX() * 0.4) < 0.01)
|
||||||
{
|
{
|
||||||
// Moving -X -Z
|
// Moving -X -Z
|
||||||
// ~ SpeedX >= 0 Immobile or not moving in the "right" direction
|
// ~ SpeedX >= 0 Immobile or not moving in the "right" direction
|
||||||
AddSpeedX(-4 / sqrt(2));
|
AddSpeedX(-4 / sqrt(2.0));
|
||||||
AddSpeedZ(-4 / sqrt(2));
|
AddSpeedZ(-4 / sqrt(2.0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ~ SpeedX < 0 Moving in the "right" direction
|
// ~ SpeedX < 0 Moving in the "right" direction
|
||||||
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2));
|
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0));
|
||||||
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2));
|
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "SetChunkData.h"
|
#include "SetChunkData.h"
|
||||||
|
#include "BlockEntities/BlockEntity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -116,3 +117,35 @@ void cSetChunkData::CalculateHeightMap(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cSetChunkData::RemoveInvalidBlockEntities(void)
|
||||||
|
{
|
||||||
|
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end();)
|
||||||
|
{
|
||||||
|
BLOCKTYPE EntityBlockType = (*itr)->GetBlockType();
|
||||||
|
BLOCKTYPE WorldBlockType = cChunkDef::GetBlock(m_BlockTypes, (*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ());
|
||||||
|
if (EntityBlockType != WorldBlockType)
|
||||||
|
{
|
||||||
|
// Bad blocktype, remove the block entity:
|
||||||
|
LOGD("Block entity blocktype mismatch at {%d, %d, %d}: entity for blocktype %s(%d) in block %s(%d). Deleting the block entity.",
|
||||||
|
(*itr)->GetPosX(), (*itr)->GetPosY(), (*itr)->GetPosZ(),
|
||||||
|
ItemTypeToString(EntityBlockType).c_str(), EntityBlockType,
|
||||||
|
ItemTypeToString(WorldBlockType).c_str(), WorldBlockType
|
||||||
|
);
|
||||||
|
cBlockEntityList::iterator itr2 = itr;
|
||||||
|
itr2++;
|
||||||
|
m_BlockEntities.erase(itr);
|
||||||
|
delete *itr;
|
||||||
|
itr = itr2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Good blocktype, keep the block entity:
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
} // for itr - m_BlockEntities[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,6 +92,9 @@ public:
|
|||||||
/** Calculates the heightmap based on the contained blocktypes and marks it valid. */
|
/** Calculates the heightmap based on the contained blocktypes and marks it valid. */
|
||||||
void CalculateHeightMap(void);
|
void CalculateHeightMap(void);
|
||||||
|
|
||||||
|
/** Removes the block entities that don't have a proper blocktype at their corresponding coords. */
|
||||||
|
void RemoveInvalidBlockEntities(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_ChunkX;
|
int m_ChunkX;
|
||||||
int m_ChunkZ;
|
int m_ChunkZ;
|
||||||
|
@ -3487,14 +3487,16 @@ void cWorld::cChunkGeneratorCallbacks::OnChunkGenerated(cChunkDesc & a_ChunkDesc
|
|||||||
cChunkDef::BlockNibbles BlockMetas;
|
cChunkDef::BlockNibbles BlockMetas;
|
||||||
a_ChunkDesc.CompressBlockMetas(BlockMetas);
|
a_ChunkDesc.CompressBlockMetas(BlockMetas);
|
||||||
|
|
||||||
m_World->QueueSetChunkData(cSetChunkDataPtr(new cSetChunkData(
|
cSetChunkDataPtr SetChunkData(new cSetChunkData(
|
||||||
a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(),
|
a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(),
|
||||||
a_ChunkDesc.GetBlockTypes(), BlockMetas,
|
a_ChunkDesc.GetBlockTypes(), BlockMetas,
|
||||||
NULL, NULL, // We don't have lighting, chunk will be lighted when needed
|
NULL, NULL, // We don't have lighting, chunk will be lighted when needed
|
||||||
&a_ChunkDesc.GetHeightMap(), &a_ChunkDesc.GetBiomeMap(),
|
&a_ChunkDesc.GetHeightMap(), &a_ChunkDesc.GetBiomeMap(),
|
||||||
a_ChunkDesc.GetEntities(), a_ChunkDesc.GetBlockEntities(),
|
a_ChunkDesc.GetEntities(), a_ChunkDesc.GetBlockEntities(),
|
||||||
true
|
true
|
||||||
)));
|
));
|
||||||
|
SetChunkData->RemoveInvalidBlockEntities();
|
||||||
|
m_World->QueueSetChunkData(SetChunkData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
|||||||
} // for y
|
} // for y
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
m_World->QueueSetChunkData(cSetChunkDataPtr(new cSetChunkData(
|
cSetChunkDataPtr SetChunkData(new cSetChunkData(
|
||||||
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
|
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
|
||||||
BlockTypes, MetaData,
|
BlockTypes, MetaData,
|
||||||
IsLightValid ? BlockLight : NULL,
|
IsLightValid ? BlockLight : NULL,
|
||||||
@ -404,7 +404,8 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
|||||||
NULL, Biomes,
|
NULL, Biomes,
|
||||||
Entities, BlockEntities,
|
Entities, BlockEntities,
|
||||||
false
|
false
|
||||||
)));
|
));
|
||||||
|
m_World->QueueSetChunkData(SetChunkData);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,64 +582,28 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int sID = a_NBT.FindChildByName(Child, "id");
|
|
||||||
if (sID < 0)
|
// Get the BlockEntity's position
|
||||||
|
int x, y, z;
|
||||||
|
if (!GetBlockEntityNBTPos(a_NBT, Child, x, y, z))
|
||||||
|
{
|
||||||
|
LOGWARNING("Bad block entity, missing the coords. Will be ignored.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int RelX = x, RelY = y, RelZ = z, ChunkX, ChunkZ;
|
||||||
|
cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
|
||||||
|
|
||||||
|
// Load the proper BlockEntity type based on the block type:
|
||||||
|
BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, RelY, RelZ);
|
||||||
|
NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, RelY, RelZ);
|
||||||
|
std::auto_ptr<cBlockEntity> be(LoadBlockEntityFromNBT(a_NBT, Child, x, y, z, BlockType, BlockMeta));
|
||||||
|
if (be.get() == NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (strncmp(a_NBT.GetData(sID), "Beacon", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
// Add the BlockEntity to the loaded data:
|
||||||
LoadBeaconFromNBT(a_BlockEntities, a_NBT, Child);
|
a_BlockEntities.push_back(be.release());
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_CHEST);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Control", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadCommandBlockFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Dropper", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadDropperFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "FlowerPot", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadFlowerPotFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child, a_BlockTypes, a_BlockMetas);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Hopper", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadHopperFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Music", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadNoteFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "RecordPlayer", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadJukeboxFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Sign", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadSignFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Skull", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadMobHeadFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child);
|
|
||||||
}
|
|
||||||
else if (strncmp(a_NBT.GetData(sID), "TrappedChest", a_NBT.GetDataLength(sID)) == 0)
|
|
||||||
{
|
|
||||||
LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_TRAPPED_CHEST);
|
|
||||||
}
|
|
||||||
// TODO: Other block entities
|
|
||||||
} // for Child - tag children
|
} // for Child - tag children
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,6 +611,52 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||||
|
{
|
||||||
|
// Load the specific BlockEntity type:
|
||||||
|
switch (a_BlockType)
|
||||||
|
{
|
||||||
|
// Specific entity loaders:
|
||||||
|
case E_BLOCK_BEACON: return LoadBeaconFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_CHEST);
|
||||||
|
case E_BLOCK_COMMAND_BLOCK: return LoadCommandBlockFromNBT(a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_DISPENSER: return LoadDispenserFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_DROPPER: return LoadDropperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_FLOWER_POT: return LoadFlowerPotFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FURNACE, a_BlockMeta);
|
||||||
|
case E_BLOCK_HEAD: return LoadMobHeadFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_HOPPER: return LoadHopperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_JUKEBOX: return LoadJukeboxFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_LIT_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LIT_FURNACE, a_BlockMeta);
|
||||||
|
case E_BLOCK_NOTE_BLOCK: return LoadNoteBlockFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SIGN_POST);
|
||||||
|
case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_TRAPPED_CHEST);
|
||||||
|
case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WALLSIGN);
|
||||||
|
|
||||||
|
// Blocktypes that have block entities but don't load their contents from disk:
|
||||||
|
case E_BLOCK_ENDER_CHEST: return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All the other blocktypes should have no entities assigned to them. Report an error:
|
||||||
|
// Get the "id" tag:
|
||||||
|
int TagID = a_NBT.FindChildByName(a_Tag, "id");
|
||||||
|
AString TypeName("<unknown>");
|
||||||
|
if (TagID >= 0)
|
||||||
|
{
|
||||||
|
TypeName.assign(a_NBT.GetData(TagID), (size_t)a_NBT.GetDataLength(TagID));
|
||||||
|
}
|
||||||
|
LOGINFO("WorldLoader(%s): Block entity mismatch: block type %s (%d), type \"%s\", at {%d, %d, %d}; the entity will be lost.",
|
||||||
|
m_World->GetName().c_str(),
|
||||||
|
ItemTypeToString(a_BlockType).c_str(), a_BlockType, TypeName.c_str(),
|
||||||
|
a_BlockX, a_BlockY, a_BlockZ
|
||||||
|
);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx)
|
bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||||
{
|
{
|
||||||
int Type = a_NBT.FindChildByName(a_TagIdx, "id");
|
int Type = a_NBT.FindChildByName(a_TagIdx, "id");
|
||||||
@ -656,7 +667,6 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
|
|||||||
a_Item.m_ItemType = a_NBT.GetShort(Type);
|
a_Item.m_ItemType = a_NBT.GetShort(Type);
|
||||||
if (a_Item.m_ItemType < 0)
|
if (a_Item.m_ItemType < 0)
|
||||||
{
|
{
|
||||||
LOGD("Encountered an item with negative type (%d). Replacing with an empty item.", a_NBT.GetShort(Type));
|
|
||||||
a_Item.Empty();
|
a_Item.Empty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -754,16 +764,46 @@ void cWSSAnvil::LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the given tag is a compound:
|
||||||
int x, y, z;
|
if (a_NBT.GetType(a_TagIdx) != TAG_Compound)
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::auto_ptr<cBeaconEntity> Beacon(new cBeaconEntity(x, y, z, m_World));
|
// Get the "id" tag:
|
||||||
|
int TagID = a_NBT.FindChildByName(a_TagIdx, "id");
|
||||||
|
if (TagID < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare the value:
|
||||||
|
if (strncmp(a_NBT.GetData(TagID), a_ExpectedType, (size_t)a_NBT.GetDataLength(TagID)) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
LOGWARNING("Block entity type mismatch: exp \"%s\", got \"%s\".",
|
||||||
|
a_ExpectedType,
|
||||||
|
AString(a_NBT.GetData(TagID), (size_t)a_NBT.GetDataLength(TagID)).c_str()
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
|
{
|
||||||
|
// Check if the data has a proper type:
|
||||||
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Beacon"))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::auto_ptr<cBeaconEntity> Beacon(new cBeaconEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
|
|
||||||
int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Levels");
|
int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Levels");
|
||||||
if (CurrentLine >= 0)
|
if (CurrentLine >= 0)
|
||||||
@ -790,88 +830,128 @@ void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cPar
|
|||||||
LoadItemGridFromNBT(Beacon->GetContents(), a_NBT, Items);
|
LoadItemGridFromNBT(Beacon->GetContents(), a_NBT, Items);
|
||||||
}
|
}
|
||||||
|
|
||||||
a_BlockEntities.push_back(Beacon.release());
|
return Beacon.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType)
|
cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_ChestBlockType)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
// TODO: Does vanilla use "TrappedChest" or not? MCWiki says no, but previous code says yes
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
// Ref.: http://minecraft.gamepedia.com/Trapped_Chest
|
||||||
|
// https://github.com/mc-server/MCServer/blob/d0551e2e0a98a28f31a88d489d17b408e4a7d38d/src/WorldStorage/WSSAnvil.cpp#L637
|
||||||
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Chest") && !CheckBlockEntityType(a_NBT, a_TagIdx, "TrappedChest"))
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||||
{
|
{
|
||||||
return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this
|
return NULL; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this
|
||||||
}
|
}
|
||||||
std::auto_ptr<cChestEntity> Chest(new cChestEntity(x, y, z, m_World, a_ChestType));
|
std::auto_ptr<cChestEntity> Chest(new cChestEntity(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType));
|
||||||
LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items);
|
LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items);
|
||||||
a_BlockEntities.push_back(Chest.release());
|
return Chest.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadDispenserFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Control"))
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::auto_ptr<cCommandBlockEntity> CmdBlock(new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
|
|
||||||
|
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
CmdBlock->SetCommand(a_NBT.GetString(currentLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLine = a_NBT.FindChildByName(a_TagIdx, "SuccessCount");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
CmdBlock->SetResult(a_NBT.GetInt(currentLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLine = a_NBT.FindChildByName(a_TagIdx, "LastOutput");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
CmdBlock->SetLastOutput(a_NBT.GetString(currentLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 2014-01-18 xdot: Figure out what TrackOutput is and parse it.
|
||||||
|
|
||||||
|
return CmdBlock.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
|
{
|
||||||
|
// Check if the data has a proper type:
|
||||||
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Trap"))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||||
{
|
{
|
||||||
return; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this
|
return NULL; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this
|
||||||
}
|
}
|
||||||
std::auto_ptr<cDispenserEntity> Dispenser(new cDispenserEntity(x, y, z, m_World));
|
std::auto_ptr<cDispenserEntity> Dispenser(new cDispenserEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
LoadItemGridFromNBT(Dispenser->GetContents(), a_NBT, Items);
|
LoadItemGridFromNBT(Dispenser->GetContents(), a_NBT, Items);
|
||||||
a_BlockEntities.push_back(Dispenser.release());
|
return Dispenser.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadDropperFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Dropper"))
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||||
{
|
{
|
||||||
return; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this
|
return NULL; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this
|
||||||
}
|
}
|
||||||
std::auto_ptr<cDropperEntity> Dropper(new cDropperEntity(x, y, z, m_World));
|
std::auto_ptr<cDropperEntity> Dropper(new cDropperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items);
|
LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items);
|
||||||
a_BlockEntities.push_back(Dropper.release());
|
return Dropper.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadFlowerPotFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "FlowerPot"))
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
std::auto_ptr<cFlowerPotEntity> FlowerPot(new cFlowerPotEntity(x, y, z, m_World));
|
|
||||||
|
std::auto_ptr<cFlowerPotEntity> FlowerPot(new cFlowerPotEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
short ItemType = 0, ItemData = 0;
|
short ItemType = 0, ItemData = 0;
|
||||||
|
|
||||||
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Item");
|
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Item");
|
||||||
@ -887,37 +967,28 @@ void cWSSAnvil::LoadFlowerPotFromNBT(cBlockEntityList & a_BlockEntities, const c
|
|||||||
}
|
}
|
||||||
|
|
||||||
FlowerPot->SetItem(cItem(ItemType, 1, ItemData));
|
FlowerPot->SetItem(cItem(ItemType, 1, ItemData));
|
||||||
a_BlockEntities.push_back(FlowerPot.release());
|
return FlowerPot.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas)
|
cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Furnace"))
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||||
{
|
{
|
||||||
return; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this
|
return NULL; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert coords to relative:
|
std::auto_ptr<cFurnaceEntity> Furnace(new cFurnaceEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World));
|
||||||
int RelX = x;
|
|
||||||
int RelZ = z;
|
|
||||||
int ChunkX, ChunkZ;
|
|
||||||
cChunkDef::AbsoluteToRelative(RelX, y, RelZ, ChunkX, ChunkZ);
|
|
||||||
|
|
||||||
// Create the furnace entity, with proper BlockType and BlockMeta info:
|
|
||||||
BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, y, RelZ);
|
|
||||||
NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, y, RelZ);
|
|
||||||
std::auto_ptr<cFurnaceEntity> Furnace(new cFurnaceEntity(x, y, z, BlockType, BlockMeta, m_World));
|
|
||||||
|
|
||||||
// Load slots:
|
// Load slots:
|
||||||
for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child))
|
for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child))
|
||||||
@ -954,86 +1025,121 @@ void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cPa
|
|||||||
|
|
||||||
// Restart cooking:
|
// Restart cooking:
|
||||||
Furnace->ContinueCooking();
|
Furnace->ContinueCooking();
|
||||||
a_BlockEntities.push_back(Furnace.release());
|
return Furnace.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadHopperFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Hopper"))
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
int Items = a_NBT.FindChildByName(a_TagIdx, "Items");
|
||||||
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List))
|
||||||
{
|
{
|
||||||
return; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this
|
return NULL; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this
|
||||||
}
|
}
|
||||||
std::auto_ptr<cHopperEntity> Hopper(new cHopperEntity(x, y, z, m_World));
|
std::auto_ptr<cHopperEntity> Hopper(new cHopperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items);
|
LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items);
|
||||||
a_BlockEntities.push_back(Hopper.release());
|
return Hopper.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadJukeboxFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "RecordPlayer"))
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
std::auto_ptr<cJukeboxEntity> Jukebox(new cJukeboxEntity(x, y, z, m_World));
|
|
||||||
|
std::auto_ptr<cJukeboxEntity> Jukebox(new cJukeboxEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
int Record = a_NBT.FindChildByName(a_TagIdx, "Record");
|
int Record = a_NBT.FindChildByName(a_TagIdx, "Record");
|
||||||
if (Record >= 0)
|
if (Record >= 0)
|
||||||
{
|
{
|
||||||
Jukebox->SetRecord(a_NBT.GetInt(Record));
|
Jukebox->SetRecord(a_NBT.GetInt(Record));
|
||||||
}
|
}
|
||||||
a_BlockEntities.push_back(Jukebox.release());
|
return Jukebox.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadNoteFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Skull"))
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
std::auto_ptr<cNoteEntity> Note(new cNoteEntity(x, y, z, m_World));
|
|
||||||
|
std::auto_ptr<cMobHeadEntity> MobHead(new cMobHeadEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
|
|
||||||
|
int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
MobHead->SetType(static_cast<eMobHeadType>(a_NBT.GetByte(currentLine)));
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLine = a_NBT.FindChildByName(a_TagIdx, "Rot");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
MobHead->SetRotation(static_cast<eMobHeadRotation>(a_NBT.GetByte(currentLine)));
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLine = a_NBT.FindChildByName(a_TagIdx, "ExtraType");
|
||||||
|
if (currentLine >= 0)
|
||||||
|
{
|
||||||
|
MobHead->SetOwner(a_NBT.GetString(currentLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MobHead.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
|
{
|
||||||
|
// Check if the data has a proper type:
|
||||||
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Music"))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::auto_ptr<cNoteEntity> NoteBlock(new cNoteEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
int note = a_NBT.FindChildByName(a_TagIdx, "note");
|
int note = a_NBT.FindChildByName(a_TagIdx, "note");
|
||||||
if (note >= 0)
|
if (note >= 0)
|
||||||
{
|
{
|
||||||
Note->SetPitch(a_NBT.GetByte(note));
|
NoteBlock->SetPitch(a_NBT.GetByte(note));
|
||||||
}
|
}
|
||||||
a_BlockEntities.push_back(Note.release());
|
return NoteBlock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType)
|
||||||
{
|
{
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
// Check if the data has a proper type:
|
||||||
int x, y, z;
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Sign"))
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
{
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
std::auto_ptr<cSignEntity> Sign(new cSignEntity(E_BLOCK_SIGN_POST, x, y, z, m_World));
|
|
||||||
|
std::auto_ptr<cSignEntity> Sign(new cSignEntity(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
|
|
||||||
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1");
|
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1");
|
||||||
if (currentLine >= 0)
|
if (currentLine >= 0)
|
||||||
@ -1059,79 +1165,7 @@ void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParse
|
|||||||
Sign->SetLine(3, a_NBT.GetString(currentLine));
|
Sign->SetLine(3, a_NBT.GetString(currentLine));
|
||||||
}
|
}
|
||||||
|
|
||||||
a_BlockEntities.push_back(Sign.release());
|
return Sign.release();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadMobHeadFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
|
||||||
{
|
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
|
||||||
int x, y, z;
|
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::auto_ptr<cMobHeadEntity> MobHead(new cMobHeadEntity(x, y, z, m_World));
|
|
||||||
|
|
||||||
int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType");
|
|
||||||
if (currentLine >= 0)
|
|
||||||
{
|
|
||||||
MobHead->SetType(static_cast<eMobHeadType>(a_NBT.GetByte(currentLine)));
|
|
||||||
}
|
|
||||||
|
|
||||||
currentLine = a_NBT.FindChildByName(a_TagIdx, "Rot");
|
|
||||||
if (currentLine >= 0)
|
|
||||||
{
|
|
||||||
MobHead->SetRotation(static_cast<eMobHeadRotation>(a_NBT.GetByte(currentLine)));
|
|
||||||
}
|
|
||||||
|
|
||||||
currentLine = a_NBT.FindChildByName(a_TagIdx, "ExtraType");
|
|
||||||
if (currentLine >= 0)
|
|
||||||
{
|
|
||||||
MobHead->SetOwner(a_NBT.GetString(currentLine));
|
|
||||||
}
|
|
||||||
|
|
||||||
a_BlockEntities.push_back(MobHead.release());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWSSAnvil::LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx)
|
|
||||||
{
|
|
||||||
ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound);
|
|
||||||
int x, y, z;
|
|
||||||
if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::auto_ptr<cCommandBlockEntity> CmdBlock(new cCommandBlockEntity(x, y, z, m_World));
|
|
||||||
|
|
||||||
int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command");
|
|
||||||
if (currentLine >= 0)
|
|
||||||
{
|
|
||||||
CmdBlock->SetCommand(a_NBT.GetString(currentLine));
|
|
||||||
}
|
|
||||||
|
|
||||||
currentLine = a_NBT.FindChildByName(a_TagIdx, "SuccessCount");
|
|
||||||
if (currentLine >= 0)
|
|
||||||
{
|
|
||||||
CmdBlock->SetResult(a_NBT.GetInt(currentLine));
|
|
||||||
}
|
|
||||||
|
|
||||||
currentLine = a_NBT.FindChildByName(a_TagIdx, "LastOutput");
|
|
||||||
if (currentLine >= 0)
|
|
||||||
{
|
|
||||||
CmdBlock->SetLastOutput(a_NBT.GetString(currentLine));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO 2014-01-18 xdot: Figure out what TrackOutput is and parse it.
|
|
||||||
|
|
||||||
a_BlockEntities.push_back(CmdBlock.release());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,6 +125,10 @@ protected:
|
|||||||
/// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1)
|
/// 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);
|
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 NULL 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
|
/// 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);
|
bool LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||||
|
|
||||||
@ -134,18 +138,21 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0);
|
void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0);
|
||||||
|
|
||||||
void LoadBeaconFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
/** Returns true iff the "id" child tag inside the specified tag equals the specified expected type. */
|
||||||
void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType);
|
bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType);
|
||||||
void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
|
||||||
void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
cBlockEntity * LoadBeaconFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
void LoadFlowerPotFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
cBlockEntity * LoadChestFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_ChestBlockType);
|
||||||
void LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas);
|
cBlockEntity * LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
void LoadHopperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
cBlockEntity * LoadDispenserFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||||
void LoadMobHeadFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
void LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
|
cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
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 LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t a_IDTagLength);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user