1
0

Refactored more of Entities and BlockEntities to use Vector3. (#4403)

This commit is contained in:
Mattes D 2019-09-29 14:59:24 +02:00 committed by GitHub
parent ba664340f3
commit 365cbc6e1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
122 changed files with 1271 additions and 861 deletions

View File

@ -275,6 +275,16 @@ return
}, },
Notes = "Returns the block Z-coord of the block entity's block", Notes = "Returns the block Z-coord of the block entity's block",
}, },
GetRelPos =
{
Returns =
{
{
Type = "Vector3i",
},
},
Notes = "Returns the relative coords of the block entity's block within its chunk",
},
GetRelX = GetRelX =
{ {
Returns = Returns =

View File

@ -1150,6 +1150,78 @@ end
{ {
Notes = "<b>OBSOLETE</b>, use Abs() instead.", Notes = "<b>OBSOLETE</b>, use Abs() instead.",
}, },
addedX =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3d",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the X axis",
},
addedXZ =
{
Params =
{
{
Name = "ofsX",
Type = "number",
},
{
Name = "ofsZ",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3d",
},
},
Notes = "Returns a copy of the vector, moved by the specified offsets on the X and Z axes",
},
addedY =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3d",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the Y axis",
},
addedZ =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3d",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the Z axis",
},
Clamp = Clamp =
{ {
Params = Params =
@ -1643,6 +1715,78 @@ end
{ {
Notes = "<b>OBSOLETE</b>, use Abs() instead.", Notes = "<b>OBSOLETE</b>, use Abs() instead.",
}, },
addedX =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3f",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the X axis",
},
addedXZ =
{
Params =
{
{
Name = "ofsX",
Type = "number",
},
{
Name = "ofsZ",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3f",
},
},
Notes = "Returns a copy of the vector, moved by the specified offsets on the X and Z axes",
},
addedY =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3f",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the Y axis",
},
addedZ =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3f",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the Z axis",
},
Clamp = Clamp =
{ {
Params = Params =
@ -2168,6 +2312,78 @@ end
{ {
Notes = "<b>OBSOLETE</b>, use Abs() instead.", Notes = "<b>OBSOLETE</b>, use Abs() instead.",
}, },
addedX =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3i",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the X axis",
},
addedXZ =
{
Params =
{
{
Name = "ofsX",
Type = "number",
},
{
Name = "ofsZ",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3i",
},
},
Notes = "Returns a copy of the vector, moved by the specified offsets on the X and Z axes",
},
addedY =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3i",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the Y axis",
},
addedZ =
{
Params =
{
{
Name = "ofs",
Type = "number",
},
},
Returns =
{
{
Type = "Vector3i",
},
},
Notes = "Returns a copy of the vector, moved by the specified offset on the Z axis",
},
Clamp = Clamp =
{ {
Params = Params =

View File

@ -3477,14 +3477,13 @@ static int tolua_cHopperEntity_GetOutputBlockPos(lua_State * tolua_S)
} }
NIBBLETYPE a_BlockMeta = static_cast<NIBBLETYPE>(tolua_tonumber(tolua_S, 2, 0)); NIBBLETYPE a_BlockMeta = static_cast<NIBBLETYPE>(tolua_tonumber(tolua_S, 2, 0));
int a_OutputX, a_OutputY, a_OutputZ; auto res = self->GetOutputBlockPos(a_BlockMeta);
bool res = self->GetOutputBlockPos(a_BlockMeta, a_OutputX, a_OutputY, a_OutputZ); tolua_pushboolean(tolua_S, res.first);
tolua_pushboolean(tolua_S, res); if (res.first)
if (res)
{ {
tolua_pushnumber(tolua_S, static_cast<lua_Number>(a_OutputX)); tolua_pushnumber(tolua_S, static_cast<lua_Number>(res.second.x));
tolua_pushnumber(tolua_S, static_cast<lua_Number>(a_OutputY)); tolua_pushnumber(tolua_S, static_cast<lua_Number>(res.second.y));
tolua_pushnumber(tolua_S, static_cast<lua_Number>(a_OutputZ)); tolua_pushnumber(tolua_S, static_cast<lua_Number>(res.second.z));
return 4; return 4;
} }
return 1; return 1;

View File

@ -572,7 +572,7 @@ void cBlockArea::CopyTo(cBlockArea & a_Into) const
for (const auto & keyPair: *m_BlockEntities) for (const auto & keyPair: *m_BlockEntities)
{ {
const auto & pos = keyPair.second->GetPos(); const auto & pos = keyPair.second->GetPos();
a_Into.m_BlockEntities->insert({keyPair.first, keyPair.second->Clone(pos.x, pos.y, pos.z)}); a_Into.m_BlockEntities->insert({keyPair.first, keyPair.second->Clone(pos)});
} }
} }
} }
@ -690,7 +690,7 @@ void cBlockArea::Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY
posX -= a_AddMinX; posX -= a_AddMinX;
posY -= a_AddMinY; posY -= a_AddMinY;
posZ -= a_AddMinZ; posZ -= a_AddMinZ;
be->SetPos(posX, posY, posZ); be->SetPos({posX, posY, posZ});
m_BlockEntities->insert({MakeIndex(posX, posY, posZ), std::move(be)}); m_BlockEntities->insert({MakeIndex(posX, posY, posZ), std::move(be)});
} }
} }
@ -735,7 +735,7 @@ void cBlockArea::Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMa
auto posX = be->GetPosX() + a_SubMinX; auto posX = be->GetPosX() + a_SubMinX;
auto posY = be->GetPosY() + a_SubMinY; auto posY = be->GetPosY() + a_SubMinY;
auto posZ = be->GetPosZ() + a_SubMinZ; auto posZ = be->GetPosZ() + a_SubMinZ;
be->SetPos(posX, posY, posZ); be->SetPos({posX, posY, posZ});
m_BlockEntities->insert({MakeIndex(posX, posY, posZ), std::move(be)}); m_BlockEntities->insert({MakeIndex(posX, posY, posZ), std::move(be)});
} }
} }
@ -1097,7 +1097,7 @@ void cBlockArea::RotateCCW(void)
auto newY = be->GetPosY(); auto newY = be->GetPosY();
auto newZ = m_Size.x - be->GetPosX() - 1; auto newZ = m_Size.x - be->GetPosX() - 1;
auto newIdx = newX + newZ * m_Size.z + newY * m_Size.x * m_Size.z; auto newIdx = newX + newZ * m_Size.z + newY * m_Size.x * m_Size.z;
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1157,7 +1157,7 @@ void cBlockArea::RotateCW(void)
auto newY = be->GetPosY(); auto newY = be->GetPosY();
auto newZ = be->GetPosX(); auto newZ = be->GetPosX();
auto newIdx = newX + newZ * m_Size.z + newY * m_Size.x * m_Size.z; auto newIdx = newX + newZ * m_Size.z + newY * m_Size.x * m_Size.z;
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1216,7 +1216,7 @@ void cBlockArea::MirrorXY(void)
auto newY = be->GetPosY(); auto newY = be->GetPosY();
auto newZ = MaxZ - be->GetPosZ(); auto newZ = MaxZ - be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ); auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1273,7 +1273,7 @@ void cBlockArea::MirrorXZ(void)
auto newY = MaxY - be->GetPosY(); auto newY = MaxY - be->GetPosY();
auto newZ = be->GetPosZ(); auto newZ = be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ); auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1330,7 +1330,7 @@ void cBlockArea::MirrorYZ(void)
auto newY = be->GetPosY(); auto newY = be->GetPosY();
auto newZ = be->GetPosZ(); auto newZ = be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ); auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1389,7 +1389,7 @@ void cBlockArea::RotateCCWNoMeta(void)
auto newY = be->GetPosY(); auto newY = be->GetPosY();
auto newZ = m_Size.x - be->GetPosX() - 1; auto newZ = m_Size.x - be->GetPosX() - 1;
auto newIdx = newX + newZ * m_Size.z + newY * m_Size.x * m_Size.z; auto newIdx = newX + newZ * m_Size.z + newY * m_Size.x * m_Size.z;
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1450,7 +1450,7 @@ void cBlockArea::RotateCWNoMeta(void)
auto newY = be->GetPosY(); auto newY = be->GetPosY();
auto newZ = be->GetPosX(); auto newZ = be->GetPosX();
auto newIdx = newX + newZ * m_Size.z + newY * m_Size.x * m_Size.z; auto newIdx = newX + newZ * m_Size.z + newY * m_Size.x * m_Size.z;
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1506,7 +1506,7 @@ void cBlockArea::MirrorXYNoMeta(void)
auto newY = be->GetPosY(); auto newY = be->GetPosY();
auto newZ = MaxZ - be->GetPosZ(); auto newZ = MaxZ - be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ); auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1560,7 +1560,7 @@ void cBlockArea::MirrorXZNoMeta(void)
auto newY = MaxY - be->GetPosY(); auto newY = MaxY - be->GetPosY();
auto newZ = be->GetPosZ(); auto newZ = be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ); auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1614,7 +1614,7 @@ void cBlockArea::MirrorYZNoMeta(void)
auto newY = be->GetPosY(); auto newY = be->GetPosY();
auto newZ = be->GetPosZ(); auto newZ = be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ); auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ); be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)}); m_BlockEntities->insert({newIdx, std::move(be)});
} }
} }
@ -1646,7 +1646,7 @@ void cBlockArea::SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a
if (cBlockEntity::IsBlockEntityBlockType(a_BlockType)) if (cBlockEntity::IsBlockEntityBlockType(a_BlockType))
{ {
NIBBLETYPE meta = HasBlockMetas() ? m_BlockMetas[idx] : 0; NIBBLETYPE meta = HasBlockMetas() ? m_BlockMetas[idx] : 0;
m_BlockEntities->insert({idx, cBlockEntity::CreateByBlockType(a_BlockType, meta, a_RelX, a_RelY, a_RelZ)}); m_BlockEntities->insert({idx, cBlockEntity::CreateByBlockType(a_BlockType, meta, {a_RelX, a_RelY, a_RelZ})});
} }
} }
} }
@ -1839,7 +1839,7 @@ void cBlockArea::SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, B
} }
if (cBlockEntity::IsBlockEntityBlockType(a_BlockType)) if (cBlockEntity::IsBlockEntityBlockType(a_BlockType))
{ {
m_BlockEntities->insert({idx, cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, a_RelX, a_RelY, a_RelZ)}); m_BlockEntities->insert({idx, cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, {a_RelX, a_RelY, a_RelZ})});
} }
} }
} }
@ -2414,7 +2414,7 @@ void cBlockArea::RelSetData(
if (cBlockEntity::IsBlockEntityBlockType(a_BlockType)) if (cBlockEntity::IsBlockEntityBlockType(a_BlockType))
{ {
// The block type should have a block entity attached to it, create an empty one: // The block type should have a block entity attached to it, create an empty one:
m_BlockEntities->insert({Index, cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, a_RelX, a_RelY, a_RelZ)}); m_BlockEntities->insert({Index, cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, {a_RelX, a_RelY, a_RelZ})});
} }
} }
} }
@ -2634,13 +2634,13 @@ void cBlockArea::MergeBlockEntities(int a_RelX, int a_RelY, int a_RelZ, const cB
auto itrSrc = a_Src.m_BlockEntities->find(srcIdx); auto itrSrc = a_Src.m_BlockEntities->find(srcIdx);
if (itrSrc != a_Src.m_BlockEntities->end()) if (itrSrc != a_Src.m_BlockEntities->end())
{ {
m_BlockEntities->insert({idx, itrSrc->second->Clone(x, y, z)}); m_BlockEntities->insert({idx, itrSrc->second->Clone({x, y, z})});
continue; continue;
} }
} }
// No BE found in a_Src, insert a new empty one: // No BE found in a_Src, insert a new empty one:
NIBBLETYPE meta = HasBlockMetas() ? m_BlockMetas[idx] : 0; NIBBLETYPE meta = HasBlockMetas() ? m_BlockMetas[idx] : 0;
m_BlockEntities->insert({idx, cBlockEntity::CreateByBlockType(type, meta, x, y, z)}); m_BlockEntities->insert({idx, cBlockEntity::CreateByBlockType(type, meta, {x, y, z})});
} // for x, z, y } // for x, z, y
} }
@ -2676,7 +2676,7 @@ void cBlockArea::RescanBlockEntities(void)
} }
// Create a new BE for this block: // Create a new BE for this block:
NIBBLETYPE meta = HasBlockMetas() ? m_BlockMetas[idx] : 0; NIBBLETYPE meta = HasBlockMetas() ? m_BlockMetas[idx] : 0;
m_BlockEntities->insert({idx, cBlockEntity::CreateByBlockType(type, meta, x, y, z)}); m_BlockEntities->insert({idx, cBlockEntity::CreateByBlockType(type, meta, {x, y, z})});
} // for x, z, y } // for x, z, y
} }
@ -2962,11 +2962,9 @@ void cBlockArea::cChunkReader::BlockEntity(cBlockEntity * a_BlockEntity)
{ {
return; return;
} }
auto areaX = a_BlockEntity->GetPosX() - m_Area.m_Origin.x; auto areaPos = a_BlockEntity->GetPos() - m_Area.m_Origin;
auto areaY = a_BlockEntity->GetPosY() - m_Area.m_Origin.y; auto Idx = m_Area.MakeIndex(areaPos);
auto areaZ = a_BlockEntity->GetPosZ() - m_Area.m_Origin.z; m_Area.m_BlockEntities->insert({Idx, a_BlockEntity->Clone(areaPos)});
auto Idx = m_Area.MakeIndex(areaX, areaY, areaZ);
m_Area.m_BlockEntities->insert({Idx, a_BlockEntity->Clone(areaX, areaY, areaZ)});
} }

View File

@ -388,6 +388,15 @@ public:
NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight.get(); } // NOTE: one byte per block! NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight.get(); } // NOTE: one byte per block!
size_t GetBlockCount(void) const { return static_cast<size_t>(m_Size.x * m_Size.y * m_Size.z); } size_t GetBlockCount(void) const { return static_cast<size_t>(m_Size.x * m_Size.y * m_Size.z); }
static size_t MakeIndexForSize(Vector3i a_RelPos, Vector3i a_Size); static size_t MakeIndexForSize(Vector3i a_RelPos, Vector3i a_Size);
/** Returns the index into the internal arrays for the specified coords */
size_t MakeIndex(Vector3i a_RelPos) const
{
return MakeIndexForSize(a_RelPos, m_Size);
}
/** OBSOLETE, use the Vector3i-based overload instead.
Returns the index into the internal arrays for the specified coords */
size_t MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const size_t MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const
{ {
return MakeIndexForSize({ a_RelX, a_RelY, a_RelZ }, m_Size); return MakeIndexForSize({ a_RelX, a_RelY, a_RelZ }, m_Size);

View File

@ -11,8 +11,8 @@
cBeaconEntity::cBeaconEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cBeaconEntity::cBeaconEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, 1, 1, a_World), super(a_BlockType, a_BlockMeta, a_Pos, 1, 1, a_World),
m_IsActive(false), m_IsActive(false),
m_BeaconLevel(0), m_BeaconLevel(0),
m_PrimaryEffect(cEntityEffect::effNoEffect), m_PrimaryEffect(cEntityEffect::effNoEffect),
@ -138,9 +138,9 @@ bool cBeaconEntity::SetSecondaryEffect(cEntityEffect::eType a_Effect)
bool cBeaconEntity::IsBeaconBlocked(void) bool cBeaconEntity::IsBeaconBlocked(void)
{ {
for (int Y = m_PosY; Y < cChunkDef::Height; ++Y) for (int Y = m_Pos.y; Y < cChunkDef::Height; ++Y)
{ {
BLOCKTYPE Block = m_World->GetBlock(m_PosX, Y, m_PosZ); BLOCKTYPE Block = m_World->GetBlock({m_Pos.x, Y, m_Pos.z});
if (!cBlockInfo::IsTransparent(Block)) if (!cBlockInfo::IsTransparent(Block))
{ {
return true; return true;
@ -195,7 +195,7 @@ void cBeaconEntity::UpdateBeacon(void)
GetWindow()->SetProperty(0, m_BeaconLevel); GetWindow()->SetProperty(0, m_BeaconLevel);
} }
Vector3d BeaconPosition(m_PosX, m_PosY, m_PosZ); Vector3d BeaconPosition(m_Pos);
GetWorld()->ForEachPlayer([=](cPlayer & a_Player) GetWorld()->ForEachPlayer([=](cPlayer & a_Player)
{ {
Vector3d Distance = BeaconPosition - a_Player.GetPosition(); Vector3d Distance = BeaconPosition - a_Player.GetPosition();
@ -233,7 +233,7 @@ void cBeaconEntity::GiveEffects(void)
bool HasSecondaryEffect = (m_BeaconLevel >= 4) && (m_PrimaryEffect != m_SecondaryEffect) && (m_SecondaryEffect > 0); bool HasSecondaryEffect = (m_BeaconLevel >= 4) && (m_PrimaryEffect != m_SecondaryEffect) && (m_SecondaryEffect > 0);
Vector3d BeaconPosition(m_PosX, m_PosY, m_PosZ); Vector3d BeaconPosition(m_Pos);
GetWorld()->ForEachPlayer([=](cPlayer & a_Player) GetWorld()->ForEachPlayer([=](cPlayer & a_Player)
{ {
auto PlayerPosition = a_Player.GetPosition(); auto PlayerPosition = a_Player.GetPosition();
@ -263,7 +263,7 @@ void cBeaconEntity::GiveEffects(void)
void cBeaconEntity::CopyFrom(const cBlockEntity & a_Src) void cBeaconEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cBeaconEntity &>(a_Src); auto & src = static_cast<const cBeaconEntity &>(a_Src);
m_BeaconLevel = src.m_BeaconLevel; m_BeaconLevel = src.m_BeaconLevel;
m_Contents.CopyFrom(src.m_Contents); m_Contents.CopyFrom(src.m_Contents);
@ -305,7 +305,7 @@ bool cBeaconEntity::UsedBy(cPlayer * a_Player)
cWindow * Window = GetWindow(); cWindow * Window = GetWindow();
if (Window == nullptr) if (Window == nullptr)
{ {
OpenWindow(new cBeaconWindow(m_PosX, m_PosY, m_PosZ, this)); OpenWindow(new cBeaconWindow(this));
Window = GetWindow(); Window = GetWindow();
} }

View File

@ -19,14 +19,16 @@
class cBeaconEntity : class cBeaconEntity :
public cBlockEntityWithItems public cBlockEntityWithItems
{ {
typedef cBlockEntityWithItems Super;
public:
// tolua_end // tolua_end
using super = cBlockEntityWithItems;
public: // tolua_export
BLOCKENTITY_PROTODEF(cBeaconEntity) BLOCKENTITY_PROTODEF(cBeaconEntity)
cBeaconEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cBeaconEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
// cBlockEntity overrides: // cBlockEntity overrides:
virtual void CopyFrom(const cBlockEntity & a_Src) override; virtual void CopyFrom(const cBlockEntity & a_Src) override;

View File

@ -9,8 +9,12 @@
#include "../ClientHandle.h" #include "../ClientHandle.h"
#include "../Blocks/BlockBed.h" #include "../Blocks/BlockBed.h"
cBedEntity::cBedEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, short a_Color):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
cBedEntity::cBedEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World, short a_Color):
super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Color(a_Color) m_Color(a_Color)
{ {
ASSERT(a_BlockType == E_BLOCK_BED); ASSERT(a_BlockType == E_BLOCK_BED);
@ -22,7 +26,7 @@ cBedEntity::cBedEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_Bloc
void cBedEntity::CopyFrom(const cBlockEntity & a_Src) void cBedEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cBedEntity &>(a_Src); auto & src = static_cast<const cBedEntity &>(a_Src);
m_Color = src.m_Color; m_Color = src.m_Color;
} }

View File

@ -14,13 +14,14 @@
class cBedEntity : class cBedEntity :
public cBlockEntity public cBlockEntity
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cBedEntity) BLOCKENTITY_PROTODEF(cBedEntity)
cBedEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, short a_Color = E_META_WOOL_RED); cBedEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World, short a_Color = E_META_WOOL_RED);
// tolua_begin // tolua_begin

View File

@ -26,12 +26,10 @@
void cBlockEntity::SetPos(int a_NewBlockX, int a_NewBlockY, int a_NewBlockZ) void cBlockEntity::SetPos(Vector3i a_NewPos)
{ {
ASSERT(m_World == nullptr); // Cannot move block entities that represent world blocks (only use this for cBlockArea's BEs) ASSERT(m_World == nullptr); // Cannot move block entities that represent world blocks (only use this for cBlockArea's BEs)
m_PosX = a_NewBlockX; m_Pos = a_NewPos;
m_PosY = a_NewBlockY;
m_PosZ = a_NewBlockZ;
} }
@ -75,29 +73,29 @@ bool cBlockEntity::IsBlockEntityBlockType(BLOCKTYPE a_BlockType)
cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World)
{ {
switch (a_BlockType) switch (a_BlockType)
{ {
case E_BLOCK_BEACON: return new cBeaconEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_BEACON: return new cBeaconEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_BED: return new cBedEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_BED: return new cBedEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_BREWING_STAND: return new cBrewingstandEntity(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_BREWING_STAND: return new cBrewingstandEntity(a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_CHEST: return new cChestEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_CHEST: return new cChestEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_COMMAND_BLOCK: return new cCommandBlockEntity(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_COMMAND_BLOCK: return new cCommandBlockEntity(a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_MOB_SPAWNER: return new cMobSpawnerEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_MOB_SPAWNER: return new cMobSpawnerEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_NOTE_BLOCK: return new cNoteEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_TRAPPED_CHEST: return new cChestEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_TRAPPED_CHEST: return new cChestEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
default: default:
{ {
LOGD("%s: Requesting creation of an unknown block entity - block type %d (%s)", LOGD("%s: Requesting creation of an unknown block entity - block type %d (%s)",
@ -113,9 +111,9 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
cBlockEntity * cBlockEntity::Clone(int a_BlockX, int a_BlockY, int a_BlockZ) cBlockEntity * cBlockEntity::Clone(Vector3i a_Pos)
{ {
auto res = std::unique_ptr<cBlockEntity>(CreateByBlockType(m_BlockType, m_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, nullptr)); auto res = std::unique_ptr<cBlockEntity>(CreateByBlockType(m_BlockType, m_BlockMeta, a_Pos, nullptr));
res->CopyFrom(*this); res->CopyFrom(*this);
return res.release(); return res.release();
} }

View File

@ -9,19 +9,19 @@
#define BLOCKENTITY_PROTODEF(classname) \ #define BLOCKENTITY_PROTODEF(classname) \
virtual bool IsA(const char * a_ClassName) const override \ virtual bool IsA(const char * a_ClassName) const override \
{ \ { \
return ((a_ClassName != nullptr) && ((strcmp(a_ClassName, #classname) == 0) || Super::IsA(a_ClassName))); \ return ((a_ClassName != nullptr) && ((strcmp(a_ClassName, #classname) == 0) || super::IsA(a_ClassName))); \
} \ } \
virtual const char * GetClass(void) const override \ virtual const char * GetClass() const override \
{ \ { \
return #classname; \ return #classname; \
} \ } \
static const char * GetClassStatic(void) \ static const char * GetClassStatic() \
{ \ { \
return #classname; \ return #classname; \
} \ } \
virtual const char * GetParentClass(void) const override \ virtual const char * GetParentClass() const override \
{ \ { \
return Super::GetClass(); \ return super::GetClass(); \
} }
@ -40,12 +40,10 @@ class cWorld;
class cBlockEntity class cBlockEntity
{ {
protected: protected:
cBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : cBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World) :
m_PosX(a_BlockX), m_Pos(a_Pos),
m_PosY(a_BlockY), m_RelX(a_Pos.x - cChunkDef::Width * FAST_FLOOR_DIV(a_Pos.x, cChunkDef::Width)),
m_PosZ(a_BlockZ), m_RelZ(a_Pos.z - cChunkDef::Width * FAST_FLOOR_DIV(a_Pos.z, cChunkDef::Width)),
m_RelX(a_BlockX - cChunkDef::Width * FAST_FLOOR_DIV(a_BlockX, cChunkDef::Width)),
m_RelZ(a_BlockZ - cChunkDef::Width * FAST_FLOOR_DIV(a_BlockZ, cChunkDef::Width)),
m_BlockType(a_BlockType), m_BlockType(a_BlockType),
m_BlockMeta(a_BlockMeta), m_BlockMeta(a_BlockMeta),
m_World(a_World) m_World(a_World)
@ -57,7 +55,7 @@ public:
virtual ~cBlockEntity() {} // force a virtual destructor in all descendants virtual ~cBlockEntity() {} // force a virtual destructor in all descendants
virtual void Destroy(void) {} virtual void Destroy() {}
void SetWorld(cWorld * a_World) void SetWorld(cWorld * a_World)
{ {
@ -66,27 +64,27 @@ public:
/** Updates the internally stored position. /** Updates the internally stored position.
Note that this should not ever be used for world-contained block entities, it is meant only for when BEs in a cBlockArea are manipulated. Note that this should not ever be used for world-contained block entities, it is meant only for when BEs in a cBlockArea are manipulated.
Asserts when the block entity is assigned to a world. */ Asserts that the block entity is not assigned to a world. */
void SetPos(int a_NewBlockX, int a_NewBlockY, int a_NewBlockZ); void SetPos(Vector3i a_NewPos);
/** Returns true if the specified blocktype is supposed to have an associated block entity. */ /** Returns true if the specified blocktype is supposed to have an associated block entity. */
static bool IsBlockEntityBlockType(BLOCKTYPE a_BlockType); static bool IsBlockEntityBlockType(BLOCKTYPE a_BlockType);
/** Creates a new block entity for the specified block type /** Creates a new block entity for the specified block type at the specified absolute pos.
If a_World is valid, then the entity is created bound to that world If a_World is valid, then the entity is created bound to that world
Returns nullptr for unknown block types. */ Returns nullptr for unknown block types. */
static cBlockEntity * CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World = nullptr); static cBlockEntity * CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World = nullptr);
/** Makes an exact copy of this block entity, except for its m_World (set to nullptr), and at a new position. /** Makes an exact copy of this block entity, except for its m_World (set to nullptr), and at a new position.
Uses CopyFrom() to copy the properties. */ Uses CopyFrom() to copy the properties. */
cBlockEntity * Clone(int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * Clone(Vector3i a_Pos);
/** Copies all properties of a_Src into this entity, except for its m_World and location. /** Copies all properties of a_Src into this entity, except for its m_World and location.
Each non-abstract descendant should override to copy its specific properties, and call Each non-abstract descendant should override to copy its specific properties, and call
Super::CopyFrom(a_Src) to copy the common ones. */ Super::CopyFrom(a_Src) to copy the common ones. */
virtual void CopyFrom(const cBlockEntity & a_Src); virtual void CopyFrom(const cBlockEntity & a_Src);
static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates static const char * GetClassStatic() // Needed for ManualBindings's ForEach templates
{ {
return "cBlockEntity"; return "cBlockEntity";
} }
@ -94,29 +92,31 @@ public:
/** Returns true if the object is the specified class, or its descendant. */ /** Returns true if the object is the specified class, or its descendant. */
virtual bool IsA(const char * a_ClassName) const { return (strcmp(a_ClassName, "cBlockEntity") == 0); } virtual bool IsA(const char * a_ClassName) const { return (strcmp(a_ClassName, "cBlockEntity") == 0); }
/** Returns the name of the tompost class (the most descendant). Used for Lua bindings to push the correct object type. */ /** Returns the name of the topmost class (the most descendant). Used for Lua bindings to push the correct object type. */
virtual const char * GetClass(void) const { return GetClassStatic(); } virtual const char * GetClass() const { return GetClassStatic(); }
/** Returns the name of the parent class, or empty string if no parent class. */ /** Returns the name of the parent class, or empty string if no parent class. */
virtual const char * GetParentClass(void) const { return ""; } virtual const char * GetParentClass() const { return ""; }
// tolua_begin // tolua_begin
// Position, in absolute block coordinates: // Position, in absolute block coordinates:
Vector3i GetPos(void) const { return Vector3i{m_PosX, m_PosY, m_PosZ}; } Vector3i GetPos() const { return m_Pos; }
int GetPosX(void) const { return m_PosX; } int GetPosX() const { return m_Pos.x; }
int GetPosY(void) const { return m_PosY; } int GetPosY() const { return m_Pos.y; }
int GetPosZ(void) const { return m_PosZ; } int GetPosZ() const { return m_Pos.z; }
BLOCKTYPE GetBlockType(void) const { return m_BlockType; } Vector3i GetRelPos() const { return Vector3i(m_RelX, m_Pos.y, m_RelZ); }
cWorld * GetWorld(void) const { return m_World; } BLOCKTYPE GetBlockType() const { return m_BlockType; }
int GetChunkX(void) const { return FAST_FLOOR_DIV(m_PosX, cChunkDef::Width); } cWorld * GetWorld() const { return m_World; }
int GetChunkZ(void) const { return FAST_FLOOR_DIV(m_PosZ, cChunkDef::Width); }
int GetRelX(void) const { return m_RelX; } int GetChunkX() const { return FAST_FLOOR_DIV(m_Pos.x, cChunkDef::Width); }
int GetRelZ(void) const { return m_RelZ; } int GetChunkZ() const { return FAST_FLOOR_DIV(m_Pos.y, cChunkDef::Width); }
int GetRelX() const { return m_RelX; }
int GetRelZ() const { return m_RelZ; }
// tolua_end // tolua_end
@ -135,9 +135,11 @@ public:
return false; return false;
} }
protected: protected:
/** Position in absolute block coordinates */ /** Position in absolute block coordinates */
int m_PosX, m_PosY, m_PosZ; Vector3i m_Pos;
/** Position relative to the chunk, used to speed up ticking */ /** Position relative to the chunk, used to speed up ticking */
int m_RelX, m_RelZ; int m_RelX, m_RelZ;

View File

@ -1,11 +1,5 @@
// BlockEntityWithItems.cpp // BlockEntityWithItems.cpp
// Implements the cBlockEntityWithItems class representing a common ancestor for all block entities that have an ItemGrid
#include "Globals.h" #include "Globals.h"
#include "BlockEntityWithItems.h" #include "BlockEntityWithItems.h"
#include "../Simulator/RedstoneSimulator.h" #include "../Simulator/RedstoneSimulator.h"
@ -17,11 +11,11 @@
cBlockEntityWithItems::cBlockEntityWithItems( cBlockEntityWithItems::cBlockEntityWithItems(
BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockType,
NIBBLETYPE a_BlockMeta, NIBBLETYPE a_BlockMeta,
int a_BlockX, int a_BlockY, int a_BlockZ, Vector3i a_Pos,
int a_ItemGridWidth, int a_ItemGridHeight, int a_ItemGridWidth, int a_ItemGridHeight,
cWorld * a_World cWorld * a_World
): ):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World), super(a_BlockType, a_BlockMeta, a_Pos, a_World),
cBlockEntityWindowOwner(this), cBlockEntityWindowOwner(this),
m_Contents(a_ItemGridWidth, a_ItemGridHeight) m_Contents(a_ItemGridWidth, a_ItemGridHeight)
{ {
@ -39,7 +33,7 @@ void cBlockEntityWithItems::Destroy(void)
cItems Pickups; cItems Pickups;
m_Contents.CopyToItems(Pickups); m_Contents.CopyToItems(Pickups);
m_Contents.Clear(); m_Contents.Clear();
m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); // Spawn in centre of block m_World->SpawnItemPickups(Pickups, m_Pos.x + 0.5, m_Pos.y + 0.5, m_Pos.z + 0.5); // Spawn in centre of block
} }
@ -48,7 +42,7 @@ void cBlockEntityWithItems::Destroy(void)
void cBlockEntityWithItems::CopyFrom(const cBlockEntity & a_Src) void cBlockEntityWithItems::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cBlockEntityWithItems &>(a_Src); auto & src = static_cast<const cBlockEntityWithItems &>(a_Src);
m_Contents.CopyFrom(src.m_Contents); m_Contents.CopyFrom(src.m_Contents);
} }
@ -69,10 +63,9 @@ void cBlockEntityWithItems::OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum)
} }
m_World->MarkChunkDirty(GetChunkX(), GetChunkZ()); m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
auto Pos = Vector3i(m_PosX, m_PosY, m_PosZ); m_World->DoWithChunkAt(m_Pos, [&](cChunk & a_Chunk)
m_World->DoWithChunkAt(Pos, [&](cChunk & a_Chunk)
{ {
m_World->GetRedstoneSimulator()->WakeUp(Pos, &a_Chunk); m_World->GetRedstoneSimulator()->WakeUp(m_Pos, &a_Chunk);
return true; return true;
} }
); );

View File

@ -26,18 +26,19 @@ class cBlockEntityWithItems :
// tolua_begin // tolua_begin
public cBlockEntityWindowOwner public cBlockEntityWindowOwner
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cBlockEntityWithItems) BLOCKENTITY_PROTODEF(cBlockEntityWithItems)
cBlockEntityWithItems( cBlockEntityWithItems(
BLOCKTYPE a_BlockType, // Type of the block that the entity represents BLOCKTYPE a_BlockType, // Type of the block that the entity represents
NIBBLETYPE a_BlockMeta, // Meta of the block that the entity represents NIBBLETYPE a_BlockMeta, // Meta of the block that the entity represents
int a_BlockX, int a_BlockY, int a_BlockZ, // Position of the block entity Vector3i a_Pos, // Abs position of the block entity
int a_ItemGridWidth, int a_ItemGridHeight, // Dimensions of the ItemGrid int a_ItemGridWidth, int a_ItemGridHeight, // Dimensions of the ItemGrid
cWorld * a_World // Optional world to assign to the entity cWorld * a_World // Optional world to assign to the entity
); );

View File

@ -11,8 +11,8 @@
cBrewingstandEntity::cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cBrewingstandEntity::cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_IsDestroyed(false), m_IsDestroyed(false),
m_IsBrewing(false), m_IsBrewing(false),
m_TimeBrewed(0), m_TimeBrewed(0),
@ -42,7 +42,7 @@ cBrewingstandEntity::~cBrewingstandEntity()
void cBrewingstandEntity::Destroy() void cBrewingstandEntity::Destroy()
{ {
m_IsDestroyed = true; m_IsDestroyed = true;
Super::Destroy(); super::Destroy();
} }
@ -51,7 +51,7 @@ void cBrewingstandEntity::Destroy()
void cBrewingstandEntity::CopyFrom(const cBlockEntity & a_Src) void cBrewingstandEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cBrewingstandEntity &>(a_Src); auto & src = static_cast<const cBrewingstandEntity &>(a_Src);
m_IsBrewing = src.m_IsBrewing; m_IsBrewing = src.m_IsBrewing;
for (size_t i = 0; i < ARRAYCOUNT(m_CurrentBrewingRecipes); ++i) for (size_t i = 0; i < ARRAYCOUNT(m_CurrentBrewingRecipes); ++i)
@ -158,7 +158,7 @@ bool cBrewingstandEntity::UsedBy(cPlayer * a_Player)
cWindow * Window = GetWindow(); cWindow * Window = GetWindow();
if (Window == nullptr) if (Window == nullptr)
{ {
OpenWindow(new cBrewingstandWindow(m_PosX, m_PosY, m_PosZ, this)); OpenWindow(new cBrewingstandWindow(this));
Window = GetWindow(); Window = GetWindow();
} }
@ -201,7 +201,7 @@ void cBrewingstandEntity::BroadcastProgress(short a_ProgressbarID, short a_Value
void cBrewingstandEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) void cBrewingstandEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{ {
Super::OnSlotChanged(a_ItemGrid, a_SlotNum); super::OnSlotChanged(a_ItemGrid, a_SlotNum);
if (m_IsDestroyed) if (m_IsDestroyed)
{ {

View File

@ -18,9 +18,14 @@ class cClientHandle;
class cBrewingstandEntity : class cBrewingstandEntity :
public cBlockEntityWithItems public cBlockEntityWithItems
{ {
typedef cBlockEntityWithItems Super; // tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public: public:
enum enum
{ {
bsLeftBottle = 0, // Left bottle slot number bsLeftBottle = 0, // Left bottle slot number
@ -38,7 +43,7 @@ public:
BLOCKENTITY_PROTODEF(cBrewingstandEntity) BLOCKENTITY_PROTODEF(cBrewingstandEntity)
/** Constructor used for normal operation */ /** Constructor used for normal operation */
cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
virtual ~cBrewingstandEntity() override; virtual ~cBrewingstandEntity() override;

View File

@ -12,16 +12,15 @@
cChestEntity::cChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cChestEntity::cChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_NumActivePlayers(0), m_NumActivePlayers(0),
m_Neighbour(nullptr) m_Neighbour(nullptr)
{ {
int ChunkX = 0, ChunkZ = 0; auto chunkCoord = cChunkDef::BlockToChunk(a_Pos);
cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ);
if ( if (
(m_World != nullptr) && (m_World != nullptr) &&
m_World->IsChunkValid(ChunkX, ChunkZ) m_World->IsChunkValid(chunkCoord.m_ChunkX, chunkCoord.m_ChunkZ)
) )
{ {
ScanNeighbours(); ScanNeighbours();
@ -50,7 +49,7 @@ cChestEntity::~cChestEntity()
void cChestEntity::CopyFrom(const cBlockEntity & a_Src) void cChestEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cChestEntity &>(a_Src); auto & src = static_cast<const cChestEntity &>(a_Src);
m_Contents.CopyFrom(src.m_Contents); m_Contents.CopyFrom(src.m_Contents);
@ -66,7 +65,7 @@ void cChestEntity::CopyFrom(const cBlockEntity & a_Src)
void cChestEntity::SendTo(cClientHandle & a_Client) void cChestEntity::SendTo(cClientHandle & a_Client)
{ {
// Send a dummy "number of players with chest open" packet to make the chest visible: // Send a dummy "number of players with chest open" packet to make the chest visible:
a_Client.SendBlockAction(m_PosX, m_PosY, m_PosZ, 1, 0, m_BlockType); a_Client.SendBlockAction(m_Pos.x, m_Pos.y, m_Pos.z, 1, 0, m_BlockType);
} }
@ -126,9 +125,8 @@ bool cChestEntity::UsedBy(cPlayer * a_Player)
// Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now // Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now
// We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first.
// The few false positives aren't much to worry about // The few false positives aren't much to worry about
int ChunkX, ChunkZ; auto chunkCoords = cChunkDef::BlockToChunk(m_Pos);
cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ); m_World->MarkChunkDirty(chunkCoords.m_ChunkX, chunkCoords.m_ChunkZ);
m_World->MarkChunkDirty(ChunkX, ChunkZ);
return true; return true;
} }
@ -152,10 +150,10 @@ void cChestEntity::ScanNeighbours()
// Scan horizontally adjacent blocks for any neighbouring chest of the same type: // Scan horizontally adjacent blocks for any neighbouring chest of the same type:
if ( if (
m_World->DoWithChestAt(m_PosX - 1, m_PosY, m_PosZ, FindNeighbour) || m_World->DoWithChestAt(m_Pos.x - 1, m_Pos.y, m_Pos.z, FindNeighbour) ||
m_World->DoWithChestAt(m_PosX + 1, m_PosY, m_PosZ, FindNeighbour) || m_World->DoWithChestAt(m_Pos.x + 1, m_Pos.y, m_Pos.z, FindNeighbour) ||
m_World->DoWithChestAt(m_PosX, m_PosY, m_PosZ - 1, FindNeighbour) || m_World->DoWithChestAt(m_Pos.x, m_Pos.y, m_Pos.z - 1, FindNeighbour) ||
m_World->DoWithChestAt(m_PosX, m_PosY, m_PosZ + 1, FindNeighbour) m_World->DoWithChestAt(m_Pos.x, m_Pos.y, m_Pos.z + 1, FindNeighbour)
) )
{ {
m_Neighbour->m_Neighbour = this; m_Neighbour->m_Neighbour = this;

View File

@ -18,9 +18,14 @@ class cClientHandle;
class cChestEntity : class cChestEntity :
public cBlockEntityWithItems public cBlockEntityWithItems
{ {
typedef cBlockEntityWithItems Super; // tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public: public:
enum enum
{ {
ContentsHeight = 3, ContentsHeight = 3,
@ -32,7 +37,7 @@ public:
BLOCKENTITY_PROTODEF(cChestEntity) BLOCKENTITY_PROTODEF(cChestEntity)
/** Constructor used for normal operation */ /** Constructor used for normal operation */
cChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
virtual ~cChestEntity() override; virtual ~cChestEntity() override;
@ -59,6 +64,7 @@ public:
/** Sets the number of players who currently have this chest open */ /** Sets the number of players who currently have this chest open */
void SetNumberOfPlayers(int a_NumActivePlayers) { m_NumActivePlayers = a_NumActivePlayers; } void SetNumberOfPlayers(int a_NumActivePlayers) { m_NumActivePlayers = a_NumActivePlayers; }
private: private:
/** Number of players who currently have this chest open */ /** Number of players who currently have this chest open */
@ -90,10 +96,9 @@ private:
} }
m_World->MarkChunkDirty(GetChunkX(), GetChunkZ()); m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
auto Pos = Vector3i(m_PosX, m_PosY, m_PosZ); m_World->DoWithChunkAt(m_Pos, [&](cChunk & a_Chunk)
m_World->DoWithChunkAt(Pos, [&](cChunk & a_Chunk)
{ {
m_World->GetRedstoneSimulator()->WakeUp(Pos, &a_Chunk); m_World->GetRedstoneSimulator()->WakeUp(m_Pos, &a_Chunk);
return true; return true;
} }
); );

View File

@ -17,8 +17,8 @@
cCommandBlockEntity::cCommandBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cCommandBlockEntity::cCommandBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World), super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_ShouldExecute(false), m_ShouldExecute(false),
m_Result(0) m_Result(0)
{ {
@ -115,7 +115,7 @@ void cCommandBlockEntity::Activate(void)
void cCommandBlockEntity::CopyFrom(const cBlockEntity & a_Src) void cCommandBlockEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cCommandBlockEntity &>(a_Src); auto & src = static_cast<const cCommandBlockEntity &>(a_Src);
m_Command = src.m_Command; m_Command = src.m_Command;
m_LastOutput = src.m_LastOutput; m_LastOutput = src.m_LastOutput;

View File

@ -20,16 +20,16 @@
class cCommandBlockEntity : class cCommandBlockEntity :
public cBlockEntity public cBlockEntity
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cCommandBlockEntity) BLOCKENTITY_PROTODEF(cCommandBlockEntity)
/** Creates a new empty command block entity */ /** Creates a new empty command block entity */
cCommandBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cCommandBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
// cBlockEntity overrides: // cBlockEntity overrides:
virtual void CopyFrom(const cBlockEntity & a_Src) override; virtual void CopyFrom(const cBlockEntity & a_Src) override;

View File

@ -13,8 +13,8 @@
cDispenserEntity::cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cDispenserEntity::cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World) super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{ {
ASSERT(a_BlockType == E_BLOCK_DISPENSER); ASSERT(a_BlockType == E_BLOCK_DISPENSER);
} }
@ -25,27 +25,24 @@ cDispenserEntity::cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
{ {
int DispX = m_RelX; Vector3i dispRelCoord(GetRelPos());
int DispY = m_PosY; auto meta = a_Chunk.GetMeta(dispRelCoord);
int DispZ = m_RelZ; AddDropSpenserDir(dispRelCoord, meta);
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); auto dispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(dispRelCoord.x, dispRelCoord.z);
AddDropSpenserDir(DispX, DispY, DispZ, Meta); if (dispChunk == nullptr)
cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(DispX, DispZ);
if (DispChunk == nullptr)
{ {
// Would dispense into / interact with a non-loaded chunk, ignore the tick // Would dispense into / interact with a non-loaded chunk, ignore the tick
return; return;
} }
BLOCKTYPE DispBlock = DispChunk->GetBlock(DispX, DispY, DispZ); BLOCKTYPE dispBlock = dispChunk->GetBlock(dispRelCoord);
int BlockX = (DispX + DispChunk->GetPosX() * cChunkDef::Width); auto dispAbsCoord = dispChunk->RelativeToAbsolute(dispRelCoord);
int BlockZ = (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
// Dispense the item: // Dispense the item:
const cItem & SlotItem = m_Contents.GetSlot(a_SlotNum); const cItem & SlotItem = m_Contents.GetSlot(a_SlotNum);
if (ItemCategory::IsMinecart(SlotItem.m_ItemType) && IsBlockRail(DispBlock)) // only actually place the minecart if there are rails! if (ItemCategory::IsMinecart(SlotItem.m_ItemType) && IsBlockRail(dispBlock)) // only actually place the minecart if there are rails!
{ {
if (m_World->SpawnMinecart(BlockX + 0.5, DispY + 0.5, BlockZ + 0.5, SlotItem.m_ItemType) != cEntity::INVALID_ID) if (m_World->SpawnMinecart(dispAbsCoord.x + 0.5, dispAbsCoord.y + 0.5, dispAbsCoord.z + 0.5, SlotItem.m_ItemType) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -55,15 +52,15 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
{ {
case E_ITEM_BUCKET: case E_ITEM_BUCKET:
{ {
LOGD("Dispensing empty bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock); LOGD("Dispensing empty bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock);
switch (DispBlock) switch (dispBlock)
{ {
case E_BLOCK_STATIONARY_WATER: case E_BLOCK_STATIONARY_WATER:
case E_BLOCK_WATER: case E_BLOCK_WATER:
{ {
if (ScoopUpLiquid(a_SlotNum, E_ITEM_WATER_BUCKET)) if (ScoopUpLiquid(a_SlotNum, E_ITEM_WATER_BUCKET))
{ {
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_AIR, 0); dispChunk->SetBlock(dispRelCoord, E_BLOCK_AIR, 0);
} }
break; break;
} }
@ -72,7 +69,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
{ {
if (ScoopUpLiquid(a_SlotNum, E_ITEM_LAVA_BUCKET)) if (ScoopUpLiquid(a_SlotNum, E_ITEM_LAVA_BUCKET))
{ {
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_AIR, 0); dispChunk->SetBlock(dispRelCoord, E_BLOCK_AIR, 0);
} }
break; break;
} }
@ -87,10 +84,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_WATER_BUCKET: case E_ITEM_WATER_BUCKET:
{ {
LOGD("Dispensing water bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock); LOGD("Dispensing water bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock);
if (EmptyLiquidBucket(DispBlock, a_SlotNum)) if (EmptyLiquidBucket(dispBlock, a_SlotNum))
{ {
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_WATER, 0); dispChunk->SetBlock(dispRelCoord, E_BLOCK_WATER, 0);
} }
else else
{ {
@ -101,10 +98,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_LAVA_BUCKET: case E_ITEM_LAVA_BUCKET:
{ {
LOGD("Dispensing lava bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock); LOGD("Dispensing lava bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock);
if (EmptyLiquidBucket(DispBlock, a_SlotNum)) if (EmptyLiquidBucket(dispBlock, a_SlotNum))
{ {
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_LAVA, 0); dispChunk->SetBlock(dispRelCoord, E_BLOCK_LAVA, 0);
} }
else else
{ {
@ -115,9 +112,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_SPAWN_EGG: case E_ITEM_SPAWN_EGG:
{ {
double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); double MobX = 0.5 + dispAbsCoord.x;
double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); double MobZ = 0.5 + dispAbsCoord.z;
if (m_World->SpawnMob(MobX, DispY, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage), false) != cEntity::INVALID_ID) if (m_World->SpawnMob(MobX, dispAbsCoord.y, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage), false) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -127,11 +124,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_BLOCK_TNT: case E_BLOCK_TNT:
{ {
// Spawn a primed TNT entity, if space allows: // Spawn a primed TNT entity, if space allows:
if (!cBlockInfo::IsSolid(DispBlock)) if (!cBlockInfo::IsSolid(dispBlock))
{ {
double TNTX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); m_World->SpawnPrimedTNT(Vector3d(0.5, 0.5, 0.5) + dispAbsCoord, 80, 0); // 80 ticks fuse, no initial velocity
double TNTZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
m_World->SpawnPrimedTNT({TNTX, DispY + 0.5, TNTZ}, 80, 0); // 80 ticks fuse, no initial velocity
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
break; break;
@ -140,9 +135,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_FLINT_AND_STEEL: case E_ITEM_FLINT_AND_STEEL:
{ {
// Spawn fire if the block in front is air. // Spawn fire if the block in front is air.
if (DispBlock == E_BLOCK_AIR) if (dispBlock == E_BLOCK_AIR)
{ {
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_FIRE, 0); dispChunk->SetBlock(dispRelCoord, E_BLOCK_FIRE, 0);
bool ItemBroke = m_Contents.DamageItem(a_SlotNum, 1); bool ItemBroke = m_Contents.DamageItem(a_SlotNum, 1);
@ -156,7 +151,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_FIRE_CHARGE: case E_ITEM_FIRE_CHARGE:
{ {
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkFireCharge, GetShootVector(Meta) * 20) != cEntity::INVALID_ID) if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkFireCharge, GetShootVector(meta) * 20) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -165,7 +160,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_ARROW: case E_ITEM_ARROW:
{ {
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkArrow, GetShootVector(Meta) * 30 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkArrow, GetShootVector(meta) * 30 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -174,7 +169,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_SNOWBALL: case E_ITEM_SNOWBALL:
{ {
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSnowball, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkSnowball, GetShootVector(meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -183,7 +178,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_EGG: case E_ITEM_EGG:
{ {
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkEgg, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkEgg, GetShootVector(meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -192,7 +187,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_BOTTLE_O_ENCHANTING: case E_ITEM_BOTTLE_O_ENCHANTING:
{ {
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkExpBottle, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID) if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkExpBottle, GetShootVector(meta) * 20 + Vector3d(0, 1, 0)) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -201,7 +196,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_POTION: case E_ITEM_POTION:
{ {
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSplashPotion, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID) if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkSplashPotion, GetShootVector(meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -215,7 +210,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
DropFromSlot(a_Chunk, a_SlotNum); DropFromSlot(a_Chunk, a_SlotNum);
break; break;
} }
if (m_World->GrowRipePlant(BlockX, DispY, BlockZ, true)) if (m_World->GrowRipePlant(dispAbsCoord.x, dispAbsCoord.y, dispAbsCoord.z, true))
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -229,16 +224,16 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_ACACIA_BOAT: case E_ITEM_ACACIA_BOAT:
case E_ITEM_DARK_OAK_BOAT: case E_ITEM_DARK_OAK_BOAT:
{ {
Vector3d SpawnPos; Vector3d spawnPos = dispAbsCoord;
if (IsBlockWater(DispBlock)) if (IsBlockWater(dispBlock))
{ {
// Water next to the dispenser, spawn a boat above the water block // Water next to the dispenser, spawn a boat above the water block
SpawnPos.Set(BlockX, DispY + 1, BlockZ); spawnPos.y += 1;
} }
else if (IsBlockWater(DispChunk->GetBlock(DispX, DispY - 1, DispZ))) else if (IsBlockWater(dispChunk->GetBlock(dispRelCoord.addedY(-1))))
{ {
// Water one block below the dispenser, spawn a boat at the dispenser's Y level // Water one block below the dispenser, spawn a boat at the dispenser's Y level
SpawnPos.Set(BlockX, DispY, BlockZ); // No adjustment needed
} }
else else
{ {
@ -247,10 +242,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
break; break;
} }
SpawnPos += GetShootVector(Meta) * 0.8; // A boat is bigger than one block. Add the shoot vector to put it outside the dispenser. spawnPos += GetShootVector(meta) * 0.8; // A boat is bigger than one block. Add the shoot vector to put it outside the dispenser.
SpawnPos += Vector3d(0.5, 0.5, 0.5); spawnPos += Vector3d(0.5, 0.5, 0.5);
if (m_World->SpawnBoat(SpawnPos, cBoat::ItemToMaterial(SlotItem))) if (m_World->SpawnBoat(spawnPos, cBoat::ItemToMaterial(SlotItem)))
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -259,7 +254,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_FIREWORK_ROCKET: case E_ITEM_FIREWORK_ROCKET:
{ {
if (SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkFirework, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID) if (SpawnProjectileFromDispenser(dispAbsCoord, cProjectileEntity::pkFirework, GetShootVector(meta) * 20 + Vector3d(0, 1, 0), &SlotItem) != cEntity::INVALID_ID)
{ {
m_Contents.ChangeSlotCount(a_SlotNum, -1); m_Contents.ChangeSlotCount(a_SlotNum, -1);
} }
@ -278,12 +273,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
UInt32 cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector, const cItem * a_Item) UInt32 cDispenserEntity::SpawnProjectileFromDispenser(Vector3i a_BlockPos, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector, const cItem * a_Item)
{ {
return m_World->CreateProjectile( return m_World->CreateProjectile(Vector3d(0.5, 0.5, 0.5) + a_BlockPos,
static_cast<double>(a_BlockX + 0.5),
static_cast<double>(a_BlockY + 0.5),
static_cast<double>(a_BlockZ + 0.5),
a_Kind, nullptr, a_Item, &a_ShootVector a_Kind, nullptr, a_Item, &a_ShootVector
); );
} }

View File

@ -11,22 +11,42 @@
class cDispenserEntity : class cDispenserEntity :
public cDropSpenserEntity public cDropSpenserEntity
{ {
typedef cDropSpenserEntity Super;
public:
// tolua_end // tolua_end
using super = cDropSpenserEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cDispenserEntity) BLOCKENTITY_PROTODEF(cDispenserEntity)
/** Constructor used for normal operation */ /** Constructor used for normal operation */
cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
// tolua_begin // tolua_begin
/** Spawns a projectile of the given kind in front of the dispenser with the specified speed. /** Spawns a projectile of the given kind in front of the dispenser with the specified speed.
a_Item is the item from the internal storage from which the projectile originated.
Returns the UniqueID of the spawned projectile, or cEntity::INVALID_ID on failure. */ Returns the UniqueID of the spawned projectile, or cEntity::INVALID_ID on failure. */
UInt32 SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_Speed, const cItem * a_Item = nullptr); UInt32 SpawnProjectileFromDispenser(
Vector3i a_BlockPos,
cProjectileEntity::eKind a_Kind,
const Vector3d & a_Speed,
const cItem * a_Item = nullptr
);
/** OBSOLETE, use the Vector3i-based overload instead.
Spawns a projectile of the given kind in front of the dispenser with the specified speed.
a_Item is the item from the internal storage from which the projectile originated.
Returns the UniqueID of the spawned projectile, or cEntity::INVALID_ID on failure. */
UInt32 SpawnProjectileFromDispenser(
int a_BlockX, int a_BlockY, int a_BlockZ,
cProjectileEntity::eKind a_Kind,
const Vector3d & a_Speed,
const cItem * a_Item = nullptr
)
{
return SpawnProjectileFromDispenser({a_BlockX, a_BlockY, a_BlockZ}, a_Kind, a_Speed, a_Item);
}
/** Returns a unit vector in the cardinal direction of where the dispenser with the specified meta would be facing. */ /** Returns a unit vector in the cardinal direction of where the dispenser with the specified meta would be facing. */
static Vector3d GetShootVector(NIBBLETYPE a_BlockMeta); static Vector3d GetShootVector(NIBBLETYPE a_BlockMeta);

View File

@ -15,8 +15,8 @@
cDropSpenserEntity::cDropSpenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cDropSpenserEntity::cDropSpenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_ShouldDropSpense(false) m_ShouldDropSpense(false)
{ {
} }
@ -39,16 +39,16 @@ cDropSpenserEntity::~cDropSpenserEntity()
void cDropSpenserEntity::AddDropSpenserDir(int & a_BlockX, int & a_BlockY, int & a_BlockZ, NIBBLETYPE a_Direction) void cDropSpenserEntity::AddDropSpenserDir(Vector3i & a_RelCoord, NIBBLETYPE a_Direction)
{ {
switch (a_Direction & E_META_DROPSPENSER_FACING_MASK) switch (a_Direction & E_META_DROPSPENSER_FACING_MASK)
{ {
case E_META_DROPSPENSER_FACING_YM: a_BlockY--; return; case E_META_DROPSPENSER_FACING_YM: a_RelCoord.y--; return;
case E_META_DROPSPENSER_FACING_YP: a_BlockY++; return; case E_META_DROPSPENSER_FACING_YP: a_RelCoord.y++; return;
case E_META_DROPSPENSER_FACING_ZM: a_BlockZ--; return; case E_META_DROPSPENSER_FACING_ZM: a_RelCoord.z--; return;
case E_META_DROPSPENSER_FACING_ZP: a_BlockZ++; return; case E_META_DROPSPENSER_FACING_ZP: a_RelCoord.z++; return;
case E_META_DROPSPENSER_FACING_XM: a_BlockX--; return; case E_META_DROPSPENSER_FACING_XM: a_RelCoord.x--; return;
case E_META_DROPSPENSER_FACING_XP: a_BlockX++; return; case E_META_DROPSPENSER_FACING_XP: a_RelCoord.x++; return;
} }
LOGWARNING("%s: Unhandled direction: %d", __FUNCTION__, a_Direction); LOGWARNING("%s: Unhandled direction: %d", __FUNCTION__, a_Direction);
return; return;
@ -75,7 +75,7 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk)
if (SlotsCnt == 0) if (SlotsCnt == 0)
{ {
// Nothing in the dropspenser, play the click sound // Nothing in the dropspenser, play the click sound
m_World->BroadcastSoundEffect("block.dispenser.fail", Vector3d(m_PosX, m_PosY, m_PosZ), 1.0f, 1.2f); m_World->BroadcastSoundEffect("block.dispenser.fail", m_Pos, 1.0f, 1.2f);
return; return;
} }
@ -85,7 +85,7 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk)
DropSpenseFromSlot(a_Chunk, OccupiedSlots[RandomSlot]); DropSpenseFromSlot(a_Chunk, OccupiedSlots[RandomSlot]);
// Broadcast a smoke and click effects: // Broadcast a smoke and click effects:
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); NIBBLETYPE Meta = a_Chunk.GetMeta(GetRelPos());
int SmokeDir = 0; int SmokeDir = 0;
switch (Meta & E_META_DROPSPENSER_FACING_MASK) switch (Meta & E_META_DROPSPENSER_FACING_MASK)
{ {
@ -97,7 +97,7 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk)
case E_META_DROPSPENSER_FACING_ZP: SmokeDir = static_cast<int>(SmokeDirection::NORTH); break; case E_META_DROPSPENSER_FACING_ZP: SmokeDir = static_cast<int>(SmokeDirection::NORTH); break;
} }
m_World->BroadcastSoundParticleEffect(EffectID::PARTICLE_SMOKE, GetPos(), SmokeDir); m_World->BroadcastSoundParticleEffect(EffectID::PARTICLE_SMOKE, GetPos(), SmokeDir);
m_World->BroadcastSoundEffect("block.dispenser.dispense", Vector3d(m_PosX, m_PosY, m_PosZ), 1.0f, 1.0f); m_World->BroadcastSoundEffect("block.dispenser.dispense", m_Pos, 1.0f, 1.0f);
} }
@ -115,7 +115,7 @@ void cDropSpenserEntity::Activate(void)
void cDropSpenserEntity::CopyFrom(const cBlockEntity & a_Src) void cDropSpenserEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cDropSpenserEntity &>(a_Src); auto & src = static_cast<const cDropSpenserEntity &>(a_Src);
m_Contents.CopyFrom(src.m_Contents); m_Contents.CopyFrom(src.m_Contents);
m_ShouldDropSpense = src.m_ShouldDropSpense; m_ShouldDropSpense = src.m_ShouldDropSpense;
@ -157,7 +157,7 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player)
cWindow * Window = GetWindow(); cWindow * Window = GetWindow();
if (Window == nullptr) if (Window == nullptr)
{ {
OpenWindow(new cDropSpenserWindow(m_PosX, m_PosY, m_PosZ, this)); OpenWindow(new cDropSpenserWindow(this));
Window = GetWindow(); Window = GetWindow();
} }
@ -177,11 +177,9 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player)
void cDropSpenserEntity::DropFromSlot(cChunk & a_Chunk, int a_SlotNum) void cDropSpenserEntity::DropFromSlot(cChunk & a_Chunk, int a_SlotNum)
{ {
int DispX = m_PosX; Vector3i dispCoord(m_Pos);
int DispY = m_PosY; auto Meta = a_Chunk.GetMeta(GetRelPos());
int DispZ = m_PosZ; AddDropSpenserDir(dispCoord, Meta);
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
AddDropSpenserDir(DispX, DispY, DispZ, Meta);
cItems Pickups; cItems Pickups;
Pickups.push_back(m_Contents.RemoveOneItem(a_SlotNum)); Pickups.push_back(m_Contents.RemoveOneItem(a_SlotNum));
@ -199,9 +197,9 @@ void cDropSpenserEntity::DropFromSlot(cChunk & a_Chunk, int a_SlotNum)
} }
double MicroX, MicroY, MicroZ; double MicroX, MicroY, MicroZ;
MicroX = DispX + 0.5; MicroX = dispCoord.x + 0.5;
MicroY = DispY + 0.4; // Slightly less than half, to accomodate actual texture hole on DropSpenser MicroY = dispCoord.y + 0.4; // Slightly less than half, to accomodate actual texture hole on DropSpenser
MicroZ = DispZ + 0.5; MicroZ = dispCoord.z + 0.5;
m_World->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ, PickupSpeedX, PickupSpeedY, PickupSpeedZ); m_World->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ, PickupSpeedX, PickupSpeedY, PickupSpeedZ);

View File

@ -26,9 +26,14 @@ class cClientHandle;
class cDropSpenserEntity : class cDropSpenserEntity :
public cBlockEntityWithItems public cBlockEntityWithItems
{ {
typedef cBlockEntityWithItems Super; // tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public: public:
enum enum
{ {
ContentsHeight = 3, ContentsHeight = 3,
@ -39,7 +44,7 @@ public:
BLOCKENTITY_PROTODEF(cDropSpenserEntity) BLOCKENTITY_PROTODEF(cDropSpenserEntity)
cDropSpenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cDropSpenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
virtual ~cDropSpenserEntity() override; virtual ~cDropSpenserEntity() override;
// cBlockEntity overrides: // cBlockEntity overrides:
@ -51,7 +56,7 @@ public:
// tolua_begin // tolua_begin
/** Modifies the block coords to match the dropspenser direction given (where the dropspensed pickups should materialize) */ /** Modifies the block coords to match the dropspenser direction given (where the dropspensed pickups should materialize) */
void AddDropSpenserDir(int & a_BlockX, int & a_BlockY, int & a_BlockZ, NIBBLETYPE a_Direction); void AddDropSpenserDir(Vector3i & a_RelCoord, NIBBLETYPE a_Direction);
/** Sets the dropspenser to dropspense an item in the next tick */ /** Sets the dropspenser to dropspense an item in the next tick */
void Activate(void); void Activate(void);

View File

@ -10,8 +10,8 @@
cDropperEntity::cDropperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cDropperEntity::cDropperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World) super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{ {
ASSERT(a_BlockType == E_BLOCK_DROPPER); ASSERT(a_BlockType == E_BLOCK_DROPPER);
} }

View File

@ -19,25 +19,22 @@
class cDropperEntity : class cDropperEntity :
public cDropSpenserEntity public cDropSpenserEntity
{ {
typedef cDropSpenserEntity Super;
public:
// tolua_end // tolua_end
using super = cDropSpenserEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cDropperEntity) BLOCKENTITY_PROTODEF(cDropperEntity)
/** Constructor used for normal operation */ /** Constructor used for normal operation */
cDropperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cDropperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
protected: protected:
// cDropSpenserEntity overrides: // cDropSpenserEntity overrides:
virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override; virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override;
/** Takes an item from slot a_SlotNum and puts it into the container in front of the dropper.
Called when there's a container directly in front of the dropper,
so the dropper should store items there, rather than dropping. */
void PutIntoContainer(cChunk & a_Chunk, int a_SlotNum, BLOCKTYPE a_ContainerBlock, int a_ContainerX, int a_ContainerY, int a_ContainerZ);
} ; // tolua_export } ; // tolua_export

View File

@ -13,8 +13,8 @@
cEnderChestEntity::cEnderChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cEnderChestEntity::cEnderChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World), super(a_BlockType, a_BlockMeta, a_Pos, a_World),
cBlockEntityWindowOwner(this) cBlockEntityWindowOwner(this)
{ {
ASSERT(a_BlockType == E_BLOCK_ENDER_CHEST); ASSERT(a_BlockType == E_BLOCK_ENDER_CHEST);
@ -40,7 +40,7 @@ cEnderChestEntity::~cEnderChestEntity()
void cEnderChestEntity::SendTo(cClientHandle & a_Client) void cEnderChestEntity::SendTo(cClientHandle & a_Client)
{ {
// Send a dummy "number of players with chest open" packet to make the chest visible: // Send a dummy "number of players with chest open" packet to make the chest visible:
a_Client.SendBlockAction(m_PosX, m_PosY, m_PosZ, 1, 0, m_BlockType); a_Client.SendBlockAction(m_Pos.x, m_Pos.y, m_Pos.z, 1, 0, m_BlockType);
} }

View File

@ -13,14 +13,15 @@ class cEnderChestEntity :
public cBlockEntity, public cBlockEntity,
public cBlockEntityWindowOwner public cBlockEntityWindowOwner
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cEnderChestEntity) BLOCKENTITY_PROTODEF(cEnderChestEntity)
cEnderChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cEnderChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
virtual ~cEnderChestEntity() override; virtual ~cEnderChestEntity() override;
// cBlockEntity overrides: // cBlockEntity overrides:

View File

@ -13,8 +13,8 @@
cFlowerPotEntity::cFlowerPotEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cFlowerPotEntity::cFlowerPotEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World) super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{ {
ASSERT(a_BlockType == E_BLOCK_FLOWER_POT); ASSERT(a_BlockType == E_BLOCK_FLOWER_POT);
} }
@ -31,7 +31,7 @@ void cFlowerPotEntity::Destroy(void)
ASSERT(m_World != nullptr); ASSERT(m_World != nullptr);
cItems Pickups; cItems Pickups;
Pickups.Add(m_Item); Pickups.Add(m_Item);
m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); m_World->SpawnItemPickups(Pickups, Vector3d(0.5, 0.5, 0.5) + m_Pos);
m_Item.Empty(); m_Item.Empty();
} }
@ -43,7 +43,7 @@ void cFlowerPotEntity::Destroy(void)
void cFlowerPotEntity::CopyFrom(const cBlockEntity & a_Src) void cFlowerPotEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cFlowerPotEntity &>(a_Src); auto & src = static_cast<const cFlowerPotEntity &>(a_Src);
m_Item = src.m_Item; m_Item = src.m_Item;
} }

View File

@ -20,16 +20,16 @@
class cFlowerPotEntity : class cFlowerPotEntity :
public cBlockEntity public cBlockEntity
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cFlowerPotEntity) BLOCKENTITY_PROTODEF(cFlowerPotEntity)
/** Creates a new flowerpot entity at the specified block coords. a_World may be nullptr */ /** Creates a new flowerpot entity at the specified block coords. a_World may be nullptr */
cFlowerPotEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cFlowerPotEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
// tolua_begin // tolua_begin

View File

@ -22,8 +22,8 @@ enum
cFurnaceEntity::cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cFurnaceEntity::cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_CurrentRecipe(nullptr), m_CurrentRecipe(nullptr),
m_IsDestroyed(false), m_IsDestroyed(false),
m_IsCooking(a_BlockType == E_BLOCK_LIT_FURNACE), m_IsCooking(a_BlockType == E_BLOCK_LIT_FURNACE),
@ -58,7 +58,7 @@ cFurnaceEntity::~cFurnaceEntity()
void cFurnaceEntity::Destroy() void cFurnaceEntity::Destroy()
{ {
m_IsDestroyed = true; m_IsDestroyed = true;
Super::Destroy(); super::Destroy();
} }
@ -67,7 +67,7 @@ void cFurnaceEntity::Destroy()
void cFurnaceEntity::CopyFrom(const cBlockEntity & a_Src) void cFurnaceEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cFurnaceEntity &>(a_Src); auto & src = static_cast<const cFurnaceEntity &>(a_Src);
m_Contents.CopyFrom(src.m_Contents); m_Contents.CopyFrom(src.m_Contents);
m_CurrentRecipe = src.m_CurrentRecipe; m_CurrentRecipe = src.m_CurrentRecipe;
@ -106,7 +106,7 @@ bool cFurnaceEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
// Reset progressbars, block type, and bail out // Reset progressbars, block type, and bail out
m_BlockType = E_BLOCK_FURNACE; m_BlockType = E_BLOCK_FURNACE;
a_Chunk.FastSetBlock(GetRelX(), m_PosY, GetRelZ(), E_BLOCK_FURNACE, m_BlockMeta); a_Chunk.FastSetBlock(GetRelPos(), E_BLOCK_FURNACE, m_BlockMeta);
UpdateProgressBars(); UpdateProgressBars();
return false; return false;
} }
@ -142,7 +142,7 @@ bool cFurnaceEntity::UsedBy(cPlayer * a_Player)
cWindow * Window = GetWindow(); cWindow * Window = GetWindow();
if (Window == nullptr) if (Window == nullptr)
{ {
OpenWindow(new cFurnaceWindow(m_PosX, m_PosY, m_PosZ, this)); OpenWindow(new cFurnaceWindow(this));
Window = GetWindow(); Window = GetWindow();
} }
@ -255,7 +255,7 @@ void cFurnaceEntity::BurnNewFuel(void)
void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{ {
Super::OnSlotChanged(a_ItemGrid, a_SlotNum); super::OnSlotChanged(a_ItemGrid, a_SlotNum);
if (m_IsDestroyed) if (m_IsDestroyed)
{ {
@ -433,6 +433,6 @@ void cFurnaceEntity::SetIsCooking(bool a_IsCooking)
if (m_IsCooking) if (m_IsCooking)
{ {
m_BlockType = E_BLOCK_LIT_FURNACE; m_BlockType = E_BLOCK_LIT_FURNACE;
m_World->FastSetBlock(m_PosX, m_PosY, m_PosZ, E_BLOCK_LIT_FURNACE, m_BlockMeta); m_World->FastSetBlock(m_Pos, E_BLOCK_LIT_FURNACE, m_BlockMeta);
} }
} }

View File

@ -18,9 +18,14 @@ class cClientHandle;
class cFurnaceEntity : class cFurnaceEntity :
public cBlockEntityWithItems public cBlockEntityWithItems
{ {
typedef cBlockEntityWithItems Super; // tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public: public:
enum enum
{ {
fsInput = 0, // Input slot number fsInput = 0, // Input slot number
@ -36,7 +41,7 @@ public:
BLOCKENTITY_PROTODEF(cFurnaceEntity) BLOCKENTITY_PROTODEF(cFurnaceEntity)
/** Constructor used for normal operation */ /** Constructor used for normal operation */
cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
virtual ~cFurnaceEntity() override; virtual ~cFurnaceEntity() override;

View File

@ -17,8 +17,8 @@
cHopperEntity::cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cHopperEntity::cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_LastMoveItemsInTick(0), m_LastMoveItemsInTick(0),
m_LastMoveItemsOutTick(0) m_LastMoveItemsOutTick(0)
{ {
@ -29,22 +29,20 @@ cHopperEntity::cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int
bool cHopperEntity::GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, int & a_OutputY, int & a_OutputZ) std::pair<bool, Vector3i> cHopperEntity::GetOutputBlockPos(NIBBLETYPE a_BlockMeta)
{ {
a_OutputX = m_PosX; auto pos = GetPos();
a_OutputY = m_PosY;
a_OutputZ = m_PosZ;
switch (a_BlockMeta) switch (a_BlockMeta)
{ {
case E_META_HOPPER_FACING_XM: a_OutputX--; return true; case E_META_HOPPER_FACING_XM: return {true, pos.addedX(-1)};
case E_META_HOPPER_FACING_XP: a_OutputX++; return true; case E_META_HOPPER_FACING_XP: return {true, pos.addedX( 1)};
case E_META_HOPPER_FACING_YM: a_OutputY--; return true; case E_META_HOPPER_FACING_YM: return {true, pos.addedY(-1)};
case E_META_HOPPER_FACING_ZM: a_OutputZ--; return true; case E_META_HOPPER_FACING_ZM: return {true, pos.addedZ(-1)};
case E_META_HOPPER_FACING_ZP: a_OutputZ++; return true; case E_META_HOPPER_FACING_ZP: return {true, pos.addedZ( 1)};
default: default:
{ {
// Not attached // Not attached
return false; return {false, pos};
} }
} }
} }
@ -55,7 +53,7 @@ bool cHopperEntity::GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, i
void cHopperEntity::CopyFrom(const cBlockEntity & a_Src) void cHopperEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cHopperEntity &>(a_Src); auto & src = static_cast<const cHopperEntity &>(a_Src);
m_LastMoveItemsInTick = src.m_LastMoveItemsInTick; m_LastMoveItemsInTick = src.m_LastMoveItemsInTick;
m_LastMoveItemsOutTick = src.m_LastMoveItemsOutTick; m_LastMoveItemsOutTick = src.m_LastMoveItemsOutTick;
@ -127,7 +125,7 @@ bool cHopperEntity::UsedBy(cPlayer * a_Player)
void cHopperEntity::OpenNewWindow(void) void cHopperEntity::OpenNewWindow(void)
{ {
OpenWindow(new cHopperWindow(m_PosX, m_PosY, m_PosZ, this)); OpenWindow(new cHopperWindow(this));
} }
@ -136,7 +134,7 @@ void cHopperEntity::OpenNewWindow(void)
bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick) bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
{ {
if (m_PosY >= cChunkDef::Height) if (m_Pos.y >= cChunkDef::Height)
{ {
// This hopper is at the top of the world, no more blocks above // This hopper is at the top of the world, no more blocks above
return false; return false;
@ -150,7 +148,7 @@ bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
// Try moving an item in: // Try moving an item in:
bool res = false; bool res = false;
switch (a_Chunk.GetBlock(m_RelX, m_PosY + 1, m_RelZ)) switch (a_Chunk.GetBlock(GetRelPos()))
{ {
case E_BLOCK_TRAPPED_CHEST: case E_BLOCK_TRAPPED_CHEST:
case E_BLOCK_CHEST: case E_BLOCK_CHEST:
@ -170,7 +168,7 @@ bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
case E_BLOCK_DROPPER: case E_BLOCK_DROPPER:
case E_BLOCK_HOPPER: case E_BLOCK_HOPPER:
{ {
res = MoveItemsFromGrid(*static_cast<cBlockEntityWithItems *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ))); res = MoveItemsFromGrid(*static_cast<cBlockEntityWithItems *>(a_Chunk.GetBlockEntity(GetRelPos().addedY(1))));
break; break;
} }
} }
@ -286,24 +284,23 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
} }
// Get the coords of the block where to output items: // Get the coords of the block where to output items:
int OutX, OutY, OutZ; auto meta = a_Chunk.GetMeta(GetRelPos());
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); auto out = GetOutputBlockPos(meta);
if (!GetOutputBlockPos(Meta, OutX, OutY, OutZ)) if (!out.first)
{ {
// Not attached to another container // Not attached to another container
return false; return false;
} }
if (OutY < 0) if (out.second.y < 0)
{ {
// Cannot output below the zero-th block level // Cannot output below the zero-th block level
return false; return false;
} }
// Convert coords to relative: // Convert coords to relative:
int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width; auto relCoord = a_Chunk.AbsoluteToRelative(out.second);
int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width; auto destChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(relCoord.x, relCoord.z);
cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ); if (destChunk == nullptr)
if (DestChunk == nullptr)
{ {
// The destination chunk has been unloaded, don't tick // The destination chunk has been unloaded, don't tick
return false; return false;
@ -311,33 +308,34 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
// Call proper moving function, based on the blocktype present at the coords: // Call proper moving function, based on the blocktype present at the coords:
bool res = false; bool res = false;
switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ)) auto absCoord = destChunk->RelativeToAbsolute(relCoord);
switch (destChunk->GetBlock(relCoord))
{ {
case E_BLOCK_TRAPPED_CHEST: case E_BLOCK_TRAPPED_CHEST:
case E_BLOCK_CHEST: case E_BLOCK_CHEST:
{ {
// Chests have special handling because of double-chests // Chests have special handling because of double-chests
res = MoveItemsToChest(*DestChunk, OutX, OutY, OutZ); res = MoveItemsToChest(*destChunk, absCoord);
break; break;
} }
case E_BLOCK_LIT_FURNACE: case E_BLOCK_LIT_FURNACE:
case E_BLOCK_FURNACE: case E_BLOCK_FURNACE:
{ {
// Furnaces have special handling because of the direction-to-slot relation // Furnaces have special handling because of the direction-to-slot relation
res = MoveItemsToFurnace(*DestChunk, OutX, OutY, OutZ, Meta); res = MoveItemsToFurnace(*destChunk, absCoord, meta);
break; break;
} }
case E_BLOCK_DISPENSER: case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER: case E_BLOCK_DROPPER:
case E_BLOCK_HOPPER: case E_BLOCK_HOPPER:
{ {
cBlockEntityWithItems * BlockEntity = static_cast<cBlockEntityWithItems *>(DestChunk->GetBlockEntity(OutX, OutY, OutZ)); auto blockEntity = static_cast<cBlockEntityWithItems *>(destChunk->GetBlockEntity(absCoord));
if (BlockEntity == nullptr) if (blockEntity == nullptr)
{ {
FLOGWARNING("{0}: A block entity was not found where expected at {1}", __FUNCTION__, Vector3i{OutX, OutY, OutZ}); FLOGWARNING("{0}: A block entity was not found where expected at {1}", __FUNCTION__, absCoord);
return false; return false;
} }
res = MoveItemsToGrid(*BlockEntity); res = MoveItemsToGrid(*blockEntity);
break; break;
} }
} }
@ -357,55 +355,52 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{ {
cChestEntity * MainChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ)); auto chestPos = GetPos().addedY(1);
if (MainChest == nullptr) auto mainChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(chestPos));
if (mainChest == nullptr)
{ {
FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, GetPos() + Vector3i{0, 1, 0}); FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, chestPos);
return false; return false;
} }
if (MoveItemsFromGrid(*MainChest)) if (MoveItemsFromGrid(*mainChest))
{ {
// Moved the item from the chest directly above the hopper // Moved the item from the chest directly above the hopper
return true; return true;
} }
// Check if the chest is a double-chest (chest directly above was empty), if so, try to move from there: // Check if the chest is a double-chest (chest directly above was empty), if so, try to move from there:
static const struct static const Vector3i neighborOfs[] =
{ {
int x, z; { 1, 1, 0},
} {-1, 1, 0},
Coords [] = { 0, 1, 1},
{ { 0, 1, -1},
{1, 0},
{-1, 0},
{0, 1},
{0, -1},
} ; } ;
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) for (const auto & ofs: neighborOfs)
{ {
int x = m_RelX + Coords[i].x; auto neighborRelCoord = ofs.addedXZ(m_RelX, m_RelZ);
int z = m_RelZ + Coords[i].z; auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(neighborRelCoord.x, neighborRelCoord.z);
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); if (neighbor == nullptr)
if (Neighbor == nullptr)
{ {
continue; continue;
} }
BLOCKTYPE Block = Neighbor->GetBlock(x, m_PosY + 1, z); BLOCKTYPE Block = neighbor->GetBlock(neighborRelCoord);
if (Block != MainChest->GetBlockType()) if (Block != mainChest->GetBlockType())
{ {
// Not the same kind of chest // Not the same kind of chest
continue; continue;
} }
cChestEntity * SideChest = static_cast<cChestEntity *>(Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z)); auto neighborAbsCoord = neighbor->RelativeToAbsolute(neighborRelCoord);
if (SideChest == nullptr) auto sideChest = static_cast<cChestEntity *>(neighbor->GetBlockEntity(neighborAbsCoord));
if (sideChest == nullptr)
{ {
FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, GetPos() + Vector3i{Coords[i].x, 1, Coords[i].z}); FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, neighborAbsCoord);
} }
else else
{ {
if (MoveItemsFromGrid(*SideChest)) if (MoveItemsFromGrid(*sideChest))
{ {
return true; return true;
} }
@ -413,7 +408,7 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
return false; return false;
} }
// The chest was single and nothing could be moved // The chest was empty
return false; return false;
} }
@ -423,27 +418,27 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
{ {
cFurnaceEntity * Furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ)); auto furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(m_Pos.addedY(1)));
if (Furnace == nullptr) if (furnace == nullptr)
{ {
FLOGWARNING("{0}: A furnace entity was not found where expected, at {1}", __FUNCTION__, GetPos() + Vector3i{0, 1, 0}); FLOGWARNING("{0}: A furnace entity was not found where expected, at {1}", __FUNCTION__, m_Pos.addedY(1));
return false; return false;
} }
// Try move from the output slot: // Try move from the output slot:
if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput)) if (MoveItemsFromSlot(*furnace, cFurnaceEntity::fsOutput))
{ {
cItem NewOutput(Furnace->GetOutputSlot()); cItem NewOutput(furnace->GetOutputSlot());
Furnace->SetOutputSlot(NewOutput.AddCount(-1)); furnace->SetOutputSlot(NewOutput.AddCount(-1));
return true; return true;
} }
// No output moved, check if we can move an empty bucket out of the fuel slot: // No output moved, check if we can move an empty bucket out of the fuel slot:
if (Furnace->GetFuelSlot().m_ItemType == E_ITEM_BUCKET) if (furnace->GetFuelSlot().m_ItemType == E_ITEM_BUCKET)
{ {
if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsFuel)) if (MoveItemsFromSlot(*furnace, cFurnaceEntity::fsFuel))
{ {
Furnace->SetFuelSlot(cItem()); furnace->SetFuelSlot(cItem());
return true; return true;
} }
} }
@ -458,7 +453,7 @@ bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
bool cHopperEntity::MoveItemsFromGrid(cBlockEntityWithItems & a_Entity) bool cHopperEntity::MoveItemsFromGrid(cBlockEntityWithItems & a_Entity)
{ {
cItemGrid & Grid = a_Entity.GetContents(); auto & Grid = a_Entity.GetContents();
int NumSlots = Grid.GetNumSlots(); int NumSlots = Grid.GetNumSlots();
for (int i = 0; i < NumSlots; i++) for (int i = 0; i < NumSlots; i++)
@ -521,13 +516,13 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl
bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ) bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, Vector3i a_Coords)
{ {
// Try the chest directly connected to the hopper: // Try the chest directly connected to the hopper:
cChestEntity * ConnectedChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)); auto ConnectedChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(a_Coords));
if (ConnectedChest == nullptr) if (ConnectedChest == nullptr)
{ {
FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, Vector3i{a_BlockX, a_BlockY, a_BlockZ}); FLOGWARNING("{0}: A chest entity was not found where expected, at {1}", __FUNCTION__, a_Coords);
return false; return false;
} }
if (MoveItemsToGrid(*ConnectedChest)) if (MoveItemsToGrid(*ConnectedChest))
@ -537,43 +532,37 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
} }
// Check if the chest is a double-chest (chest block directly connected was full), if so, try to move into the other half: // Check if the chest is a double-chest (chest block directly connected was full), if so, try to move into the other half:
static const struct static const Vector3i neighborOfs [] =
{ {
int x, z; { 1, 0, 0},
} {-1, 0, 0},
Coords [] = { 0, 0, 1},
{ { 0, 0, -1},
{1, 0},
{-1, 0},
{0, 1},
{0, -1},
} ; } ;
int RelX = a_BlockX - a_Chunk.GetPosX() * cChunkDef::Width; auto relCoord = a_Chunk.AbsoluteToRelative(a_Coords);
int RelZ = a_BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width; for (const auto & ofs: neighborOfs)
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{ {
int x = RelX + Coords[i].x; auto otherHalfRelCoord = relCoord + ofs;
int z = RelZ + Coords[i].z; auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(otherHalfRelCoord.x, otherHalfRelCoord.z);
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); if (neighbor == nullptr)
if (Neighbor == nullptr)
{ {
continue; continue;
} }
BLOCKTYPE Block = Neighbor->GetBlock(x, a_BlockY, z); auto Block = neighbor->GetBlock(otherHalfRelCoord);
if (Block != ConnectedChest->GetBlockType()) if (Block != ConnectedChest->GetBlockType())
{ {
// Not the same kind of chest // Not the same kind of chest
continue; continue;
} }
cChestEntity * Chest = static_cast<cChestEntity *>(Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)); auto chest = static_cast<cChestEntity *>(neighbor->GetBlockEntity(a_Coords + ofs));
if (Chest == nullptr) if (chest == nullptr)
{ {
FLOGWARNING("{0}: A chest entity was not found where expected, at {1} ({2}, {3}})", __FUNCTION__, Vector3i{a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z}, x, z); FLOGWARNING("{0}: A chest entity was not found where expected, at {1} ({2}, {3}})", __FUNCTION__, a_Coords + ofs, ofs.x, ofs.z);
continue; continue;
} }
if (MoveItemsToGrid(*Chest)) if (MoveItemsToGrid(*chest))
{ {
return true; return true;
} }
@ -588,18 +577,18 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
bool cHopperEntity::MoveItemsToFurnace(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_HopperMeta) bool cHopperEntity::MoveItemsToFurnace(cChunk & a_Chunk, Vector3i a_Coords, NIBBLETYPE a_HopperMeta)
{ {
cFurnaceEntity * Furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)); auto furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(a_Coords));
if (a_HopperMeta == E_META_HOPPER_FACING_YM) if (a_HopperMeta == E_META_HOPPER_FACING_YM)
{ {
// Feed the input slot of the furnace // Feed the input slot of the furnace
return MoveItemsToSlot(*Furnace, cFurnaceEntity::fsInput); return MoveItemsToSlot(*furnace, cFurnaceEntity::fsInput);
} }
else else
{ {
// Feed the fuel slot of the furnace // Feed the fuel slot of the furnace
return MoveItemsToSlot(*Furnace, cFurnaceEntity::fsFuel); return MoveItemsToSlot(*furnace, cFurnaceEntity::fsFuel);
} }
} }

View File

@ -19,7 +19,11 @@
class cHopperEntity : class cHopperEntity :
public cBlockEntityWithItems public cBlockEntityWithItems
{ {
typedef cBlockEntityWithItems Super; // tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public: public:
enum enum
@ -34,12 +38,12 @@ public:
BLOCKENTITY_PROTODEF(cHopperEntity) BLOCKENTITY_PROTODEF(cHopperEntity)
/** Constructor used for normal operation */ /** Constructor used for normal operation */
cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
/** Returns the block coords of the block receiving the output items, based on the meta /** Returns the block coords of the block receiving the output items, based on the meta
Returns false if unattached. Returns <false, undefined> if unattached.
Exported in ManualBindings.cpp. */ Exported in ManualBindings.cpp. */
bool GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, int & a_OutputY, int & a_OutputZ); std::pair<bool, Vector3i> GetOutputBlockPos(NIBBLETYPE a_BlockMeta);
protected: protected:
@ -76,11 +80,11 @@ protected:
/** Moves one piece from the specified itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack. */ /** Moves one piece from the specified itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack. */
bool MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SrcSlotNum); bool MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SrcSlotNum);
/** Moves items to the chest at the specified coords. Returns true if contents have changed */ /** Moves items to the chest at the specified absolute coords. Returns true if contents have changed */
bool MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ); bool MoveItemsToChest(cChunk & a_Chunk, Vector3i a_Coords);
/** Moves items to the furnace at the specified coords. Returns true if contents have changed */ /** Moves items to the furnace at the specified absolute coords. Returns true if contents have changed */
bool MoveItemsToFurnace(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_HopperMeta); bool MoveItemsToFurnace(cChunk & a_Chunk, Vector3i a_Coords, NIBBLETYPE a_HopperMeta);
/** Moves items to the specified ItemGrid. Returns true if contents have changed */ /** Moves items to the specified ItemGrid. Returns true if contents have changed */
bool MoveItemsToGrid(cBlockEntityWithItems & a_Entity); bool MoveItemsToGrid(cBlockEntityWithItems & a_Entity);

View File

@ -10,8 +10,8 @@
cJukeboxEntity::cJukeboxEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cJukeboxEntity::cJukeboxEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World), super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Record(0) m_Record(0)
{ {
ASSERT(a_BlockType == E_BLOCK_JUKEBOX); ASSERT(a_BlockType == E_BLOCK_JUKEBOX);
@ -31,7 +31,7 @@ cJukeboxEntity::~cJukeboxEntity()
void cJukeboxEntity::CopyFrom(const cBlockEntity & a_Src) void cJukeboxEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cJukeboxEntity &>(a_Src); auto & src = static_cast<const cJukeboxEntity &>(a_Src);
m_Record = src.m_Record; m_Record = src.m_Record;
} }
@ -77,7 +77,7 @@ bool cJukeboxEntity::PlayRecord(int a_Record)
} }
m_Record = a_Record; m_Record = a_Record;
m_World->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_PLAY_MUSIC_DISC, GetPos(), m_Record); m_World->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_PLAY_MUSIC_DISC, GetPos(), m_Record);
m_World->SetBlockMeta(m_PosX, m_PosY, m_PosZ, E_META_JUKEBOX_ON); m_World->SetBlockMeta(m_Pos, E_META_JUKEBOX_ON);
return true; return true;
} }
@ -96,9 +96,9 @@ bool cJukeboxEntity::EjectRecord(void)
cItems Drops; cItems Drops;
Drops.push_back(cItem(static_cast<short>(m_Record), 1, 0)); Drops.push_back(cItem(static_cast<short>(m_Record), 1, 0));
m_Record = 0; m_Record = 0;
m_World->SpawnItemPickups(Drops, m_PosX + 0.5, m_PosY + 1, m_PosZ + 0.5, 8); m_World->SpawnItemPickups(Drops, Vector3d(0.5, 1, 0.5) + m_Pos, 8);
m_World->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_PLAY_MUSIC_DISC, GetPos(), 0); m_World->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_PLAY_MUSIC_DISC, GetPos(), 0);
m_World->SetBlockMeta(m_PosX, m_PosY, m_PosZ, E_META_JUKEBOX_OFF); m_World->SetBlockMeta(m_Pos, E_META_JUKEBOX_OFF);
return true; return true;
} }

View File

@ -12,15 +12,15 @@
class cJukeboxEntity : class cJukeboxEntity :
public cBlockEntity public cBlockEntity
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cJukeboxEntity) BLOCKENTITY_PROTODEF(cJukeboxEntity)
cJukeboxEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cJukeboxEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
virtual ~cJukeboxEntity() override; virtual ~cJukeboxEntity() override;
// tolua_begin // tolua_begin

View File

@ -13,8 +13,8 @@
cMobHeadEntity::cMobHeadEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cMobHeadEntity::cMobHeadEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World), super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Type(SKULL_TYPE_SKELETON), m_Type(SKULL_TYPE_SKELETON),
m_Rotation(SKULL_ROTATION_NORTH) m_Rotation(SKULL_ROTATION_NORTH)
{ {
@ -27,7 +27,7 @@ cMobHeadEntity::cMobHeadEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, in
void cMobHeadEntity::CopyFrom(const cBlockEntity & a_Src) void cMobHeadEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cMobHeadEntity &>(a_Src); auto & src = static_cast<const cMobHeadEntity &>(a_Src);
m_OwnerName = src.m_OwnerName; m_OwnerName = src.m_OwnerName;
m_OwnerTexture = src.m_OwnerTexture; m_OwnerTexture = src.m_OwnerTexture;
@ -125,7 +125,7 @@ void cMobHeadEntity::SetOwner(const cUUID & a_OwnerUUID, const AString & a_Owner
void cMobHeadEntity::SendTo(cClientHandle & a_Client) void cMobHeadEntity::SendTo(cClientHandle & a_Client)
{ {
cWorld * World = a_Client.GetPlayer()->GetWorld(); cWorld * World = a_Client.GetPlayer()->GetWorld();
a_Client.SendBlockChange(m_PosX, m_PosY, m_PosZ, m_BlockType, World->GetBlockMeta(GetPos())); a_Client.SendBlockChange(m_Pos.x, m_Pos.y, m_Pos.z, m_BlockType, World->GetBlockMeta(GetPos()));
a_Client.SendUpdateBlockEntity(*this); a_Client.SendUpdateBlockEntity(*this);
} }

View File

@ -21,16 +21,16 @@
class cMobHeadEntity : class cMobHeadEntity :
public cBlockEntity public cBlockEntity
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cMobHeadEntity) BLOCKENTITY_PROTODEF(cMobHeadEntity)
/** Creates a new mob head entity at the specified block coords. a_World may be nullptr */ /** Creates a new mob head entity at the specified block coords. a_World may be nullptr */
cMobHeadEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cMobHeadEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
// tolua_begin // tolua_begin

View File

@ -13,8 +13,8 @@
cMobSpawnerEntity::cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cMobSpawnerEntity::cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World), super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Entity(mtPig), m_Entity(mtPig),
m_SpawnDelay(100), m_SpawnDelay(100),
m_IsActive(false) m_IsActive(false)
@ -28,7 +28,7 @@ cMobSpawnerEntity::cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMe
void cMobSpawnerEntity::CopyFrom(const cBlockEntity & a_Src) void cMobSpawnerEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cMobSpawnerEntity &>(a_Src); auto & src = static_cast<const cMobSpawnerEntity &>(a_Src);
m_Entity = src.m_Entity; m_Entity = src.m_Entity;
m_IsActive = src.m_IsActive; m_IsActive = src.m_IsActive;
@ -152,7 +152,7 @@ void cMobSpawnerEntity::SpawnEntity(void)
} }
int RelX = m_RelX + static_cast<int>((Random.RandReal<double>() - Random.RandReal<double>()) * 4.0); int RelX = m_RelX + static_cast<int>((Random.RandReal<double>() - Random.RandReal<double>()) * 4.0);
int RelY = m_PosY + Random.RandInt(-1, 1); int RelY = m_Pos.y + Random.RandInt(-1, 1);
int RelZ = m_RelZ + static_cast<int>((Random.RandReal<double>() - Random.RandReal<double>()) * 4.0); int RelZ = m_RelZ + static_cast<int>((Random.RandReal<double>() - Random.RandReal<double>()) * 4.0);
cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelX, RelZ); cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelX, RelZ);
@ -203,7 +203,7 @@ void cMobSpawnerEntity::SpawnEntity(void)
int cMobSpawnerEntity::GetNearbyPlayersNum(void) int cMobSpawnerEntity::GetNearbyPlayersNum(void)
{ {
Vector3d SpawnerPos(m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); auto SpawnerPos = Vector3d(0.5, 0.5, 0.5) + m_Pos;
int NumPlayers = 0; int NumPlayers = 0;
class cCallback : public cChunkDataCallback class cCallback : public cChunkDataCallback
@ -246,7 +246,7 @@ int cMobSpawnerEntity::GetNearbyPlayersNum(void)
int cMobSpawnerEntity::GetNearbyMonsterNum(eMonsterType a_EntityType) int cMobSpawnerEntity::GetNearbyMonsterNum(eMonsterType a_EntityType)
{ {
Vector3d SpawnerPos(m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); auto SpawnerPos = Vector3d(0.5, 0.5, 0.5) + m_Pos;
int NumEntities = 0; int NumEntities = 0;
class cCallback : public cChunkDataCallback class cCallback : public cChunkDataCallback

View File

@ -16,16 +16,16 @@
// tolua_begin // tolua_begin
class cMobSpawnerEntity : class cMobSpawnerEntity :
public cBlockEntity public cBlockEntity
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); using super = cBlockEntity;
public: // tolua_export
cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
// cBlockEntity overrides: // cBlockEntity overrides:
virtual void CopyFrom(const cBlockEntity & a_Src) override; virtual void CopyFrom(const cBlockEntity & a_Src) override;

View File

@ -9,8 +9,8 @@
cNoteEntity::cNoteEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cNoteEntity::cNoteEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World), super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Pitch(0) m_Pitch(0)
{ {
ASSERT(a_BlockType == E_BLOCK_NOTE_BLOCK); ASSERT(a_BlockType == E_BLOCK_NOTE_BLOCK);
@ -22,7 +22,7 @@ cNoteEntity::cNoteEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_Bl
void cNoteEntity::CopyFrom(const cBlockEntity & a_Src) void cNoteEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cNoteEntity &>(a_Src); auto & src = static_cast<const cNoteEntity &>(a_Src);
m_Pitch = src.m_Pitch; m_Pitch = src.m_Pitch;
} }
@ -48,7 +48,7 @@ void cNoteEntity::MakeSound(void)
char instrument; char instrument;
AString sampleName; AString sampleName;
switch (m_World->GetBlock(m_PosX, m_PosY - 1, m_PosZ)) switch (m_World->GetBlock(m_Pos.addedY(-1)))
{ {
case E_BLOCK_ACACIA_DOOR: case E_BLOCK_ACACIA_DOOR:
case E_BLOCK_ACACIA_FENCE: case E_BLOCK_ACACIA_FENCE:
@ -243,13 +243,13 @@ void cNoteEntity::MakeSound(void)
} }
} }
m_World->BroadcastBlockAction({m_PosX, m_PosY, m_PosZ}, static_cast<Byte>(instrument), static_cast<Byte>(m_Pitch), E_BLOCK_NOTE_BLOCK); m_World->BroadcastBlockAction(m_Pos, static_cast<Byte>(instrument), static_cast<Byte>(m_Pitch), E_BLOCK_NOTE_BLOCK);
// TODO: instead of calculating the power function over and over, make a precalculated table - there's only 24 pitches after all // TODO: instead of calculating the power function over and over, make a precalculated table - there's only 24 pitches after all
float calcPitch = static_cast<float>(pow(2.0f, static_cast<float>(m_Pitch - 12.0f) / 12.0f)); float calcPitch = static_cast<float>(pow(2.0f, static_cast<float>(m_Pitch - 12.0f) / 12.0f));
m_World->BroadcastSoundEffect( m_World->BroadcastSoundEffect(
sampleName, sampleName,
Vector3d(m_PosX, m_PosY, m_PosZ), m_Pos,
3.0f, 3.0f,
calcPitch calcPitch
); );

View File

@ -30,15 +30,16 @@ enum ENUM_NOTE_INSTRUMENTS
class cNoteEntity : class cNoteEntity :
public cBlockEntity public cBlockEntity
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cNoteEntity) BLOCKENTITY_PROTODEF(cNoteEntity)
/** Creates a new note entity. a_World may be nullptr */ /** Creates a new note entity. a_World may be nullptr */
cNoteEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cNoteEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
virtual ~cNoteEntity() override {} virtual ~cNoteEntity() override {}
// tolua_begin // tolua_begin

View File

@ -12,11 +12,11 @@
cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World): cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World) super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{ {
ASSERT((a_BlockType == E_BLOCK_WALLSIGN) || (a_BlockType == E_BLOCK_SIGN_POST)); ASSERT((a_BlockType == E_BLOCK_WALLSIGN) || (a_BlockType == E_BLOCK_SIGN_POST));
ASSERT(cChunkDef::IsValidHeight(a_BlockY)); ASSERT(cChunkDef::IsValidHeight(a_Pos.y));
} }
@ -25,7 +25,7 @@ cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_Bl
void cSignEntity::CopyFrom(const cBlockEntity & a_Src) void cSignEntity::CopyFrom(const cBlockEntity & a_Src)
{ {
Super::CopyFrom(a_Src); super::CopyFrom(a_Src);
auto & src = static_cast<const cSignEntity &>(a_Src); auto & src = static_cast<const cSignEntity &>(a_Src);
for (size_t i = 0; i < ARRAYCOUNT(m_Line); ++i) for (size_t i = 0; i < ARRAYCOUNT(m_Line); ++i)
{ {
@ -89,5 +89,5 @@ AString cSignEntity::GetLine(int a_Index) const
void cSignEntity::SendTo(cClientHandle & a_Client) void cSignEntity::SendTo(cClientHandle & a_Client)
{ {
a_Client.SendUpdateSign(m_PosX, m_PosY, m_PosZ, m_Line[0], m_Line[1], m_Line[2], m_Line[3]); a_Client.SendUpdateSign(m_Pos.x, m_Pos.y, m_Pos.z, m_Line[0], m_Line[1], m_Line[2], m_Line[3]);
} }

View File

@ -19,16 +19,16 @@
class cSignEntity : class cSignEntity :
public cBlockEntity public cBlockEntity
{ {
typedef cBlockEntity Super;
public:
// tolua_end // tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cSignEntity) BLOCKENTITY_PROTODEF(cSignEntity)
/** Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be nullptr */ /** Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be nullptr */
cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
// tolua_begin // tolua_begin

View File

@ -89,7 +89,7 @@ public:
// New knot? needs to init and produce sound effect // New knot? needs to init and produce sound effect
else else
{ {
auto NewLeashKnot = cpp14::make_unique<cLeashKnot>(a_BlockFace, a_BlockX, a_BlockY, a_BlockZ); auto NewLeashKnot = cpp14::make_unique<cLeashKnot>(a_BlockFace, Vector3i{a_BlockX, a_BlockY, a_BlockZ});
auto NewLeashKnotPtr = NewLeashKnot.get(); auto NewLeashKnotPtr = NewLeashKnot.get();
NewLeashKnotPtr->TiePlayersLeashedMobs(a_Player, KnotAlreadyExists); NewLeashKnotPtr->TiePlayersLeashedMobs(a_Player, KnotAlreadyExists);

View File

@ -464,7 +464,7 @@ void cChunk::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlock
{ {
m_BlockEntities.erase(itr); m_BlockEntities.erase(itr);
} }
auto clone = be->Clone(posX, posY, posZ); auto clone = be->Clone({posX, posY, posZ});
clone->SetWorld(m_World); clone->SetWorld(m_World);
AddBlockEntityClean(clone); AddBlockEntityClean(clone);
m_World->BroadcastBlockEntity({posX, posY, posZ}); m_World->BroadcastBlockEntity({posX, posY, posZ});
@ -1047,7 +1047,7 @@ bool cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Bl
Meta Meta
); );
VERIFY(UnboundedRelFastSetBlock(a_RelX + x, a_RelY, a_RelZ + z, ProduceType, Meta)); VERIFY(UnboundedRelFastSetBlock(a_RelX + x, a_RelY, a_RelZ + z, ProduceType, Meta));
auto Absolute = RelativeToAbsolute(Vector3i{a_RelX + x, a_RelY, a_RelZ + z}, m_PosX, m_PosZ); auto Absolute = RelativeToAbsolute(Vector3i{a_RelX + x, a_RelY, a_RelZ + z});
cChunkInterface ChunkInterface(this->GetWorld()->GetChunkMap()); cChunkInterface ChunkInterface(this->GetWorld()->GetChunkMap());
cBlockHandler::NeighborChanged(ChunkInterface, Absolute.x, Absolute.y - 1, Absolute.z, BLOCK_FACE_YP); cBlockHandler::NeighborChanged(ChunkInterface, Absolute.x, Absolute.y - 1, Absolute.z, BLOCK_FACE_YP);
break; break;
@ -1435,12 +1435,12 @@ void cChunk::CreateBlockEntities(void)
{ {
auto RelPos = IndexToCoordinate(BlockIdx); auto RelPos = IndexToCoordinate(BlockIdx);
RelPos.y += static_cast<int>(SectionIdx * cChunkData::SectionHeight); RelPos.y += static_cast<int>(SectionIdx * cChunkData::SectionHeight);
auto WorldPos = RelativeToAbsolute(RelPos, m_PosX, m_PosZ); auto WorldPos = RelativeToAbsolute(RelPos);
if (!HasBlockEntityAt(WorldPos)) if (!HasBlockEntityAt(WorldPos))
{ {
AddBlockEntityClean(cBlockEntity::CreateByBlockType( AddBlockEntityClean(cBlockEntity::CreateByBlockType(
BlockType, GetMeta(RelPos), WorldPos.x, WorldPos.y, WorldPos.z, m_World BlockType, GetMeta(RelPos), WorldPos, m_World
)); ));
} }
} }
@ -1475,7 +1475,7 @@ void cChunk::WakeUpSimulators(void)
{ {
auto RelPos = IndexToCoordinate(BlockIdx); auto RelPos = IndexToCoordinate(BlockIdx);
RelPos.y += static_cast<int>(SectionIdx * cChunkData::SectionHeight); RelPos.y += static_cast<int>(SectionIdx * cChunkData::SectionHeight);
return RelativeToAbsolute(RelPos, m_PosX, m_PosZ); return RelativeToAbsolute(RelPos);
}; };
// The redstone sim takes multiple blocks, use the inbuilt checker // The redstone sim takes multiple blocks, use the inbuilt checker
@ -1576,7 +1576,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
case E_BLOCK_BREWING_STAND: case E_BLOCK_BREWING_STAND:
{ {
// Fast set block has already marked dirty // Fast set block has already marked dirty
AddBlockEntityClean(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, WorldPos.x, WorldPos.y, WorldPos.z, m_World)); AddBlockEntityClean(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, WorldPos, m_World));
break; break;
} }
} // switch (a_BlockType) } // switch (a_BlockType)

View File

@ -479,6 +479,14 @@ public:
return cChunkClientHandles(m_LoadedByClient); return cChunkClientHandles(m_LoadedByClient);
} }
/** Converts the coord relative to this chunk into an absolute coord.
Doesn't check relative coord validity. */
Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition)
{
return cChunkDef::RelativeToAbsolute(a_RelBlockPosition, m_PosX, m_PosZ);
}
private: private:
friend class cChunkMap; friend class cChunkMap;

View File

@ -245,6 +245,14 @@ public:
} }
inline static int MakeIndexNoCheck(Vector3i a_RelPos)
{
return MakeIndexNoCheck(a_RelPos.x, a_RelPos.y, a_RelPos.z);
}
inline static Vector3i IndexToCoordinate(size_t index) inline static Vector3i IndexToCoordinate(size_t index)
{ {
#if AXIS_ORDER == AXIS_ORDER_XZY #if AXIS_ORDER == AXIS_ORDER_XZY
@ -279,6 +287,13 @@ public:
} }
inline static BLOCKTYPE GetBlock(const BLOCKTYPE * a_BlockTypes, Vector3i a_RelPos)
{
ASSERT(IsValidRelPos(a_RelPos));
return a_BlockTypes[MakeIndexNoCheck(a_RelPos)];
}
inline static BLOCKTYPE GetBlock(const BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z) inline static BLOCKTYPE GetBlock(const BLOCKTYPE * a_BlockTypes, int a_X, int a_Y, int a_Z)
{ {
ASSERT((a_X >= 0) && (a_X < Width)); ASSERT((a_X >= 0) && (a_X < Width));
@ -358,6 +373,18 @@ public:
} }
static NIBBLETYPE GetNibble(const NIBBLETYPE * a_Buffer, Vector3i a_RelPos)
{
if (IsValidRelPos(a_RelPos))
{
auto Index = MakeIndexNoCheck(a_RelPos);
return (a_Buffer[static_cast<size_t>(Index / 2)] >> ((Index & 1) * 4)) & 0x0f;
}
ASSERT(!"Coords out of chunk range!");
return 0;
}
static NIBBLETYPE GetNibble(const NIBBLETYPE * a_Buffer, int x, int y, int z) static NIBBLETYPE GetNibble(const NIBBLETYPE * a_Buffer, int x, int y, int z)
{ {
if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1))

View File

@ -8,8 +8,8 @@
cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : cArrowEntity::cArrowEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkArrow, a_Creator, a_X, a_Y, a_Z, 0.5, 0.5), super(pkArrow, a_Creator, a_Pos, 0.5, 0.5),
m_PickupState(psNoPickup), m_PickupState(psNoPickup),
m_DamageCoeff(2), m_DamageCoeff(2),
m_IsCritical(false), m_IsCritical(false),

View File

@ -20,9 +20,15 @@
class cArrowEntity : class cArrowEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super; // tolua_end
using super = cProjectileEntity;
// tolua_begin
public: public:
/** Determines when the arrow can be picked up (depending on player gamemode). Corresponds to the MCA file "pickup" field */ /** Determines when the arrow can be picked up (depending on player gamemode). Corresponds to the MCA file "pickup" field */
enum ePickupState enum ePickupState
{ {
@ -36,7 +42,7 @@ public:
CLASS_PROTODEF(cArrowEntity) CLASS_PROTODEF(cArrowEntity)
/** Creates a new arrow with psNoPickup state and default damage modifier coeff */ /** Creates a new arrow with psNoPickup state and default damage modifier coeff */
cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); cArrowEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed);
/** Creates a new arrow as shot by a player, initializes it from the player object */ /** Creates a new arrow as shot by a player, initializes it from the player object */
cArrowEntity(cPlayer & a_Player, double a_Force); cArrowEntity(cPlayer & a_Player, double a_Force);

View File

@ -14,7 +14,7 @@
cBoat::cBoat(Vector3d a_Pos, eMaterial a_Material) : cBoat::cBoat(Vector3d a_Pos, eMaterial a_Material) :
super(etBoat, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.7), super(etBoat, a_Pos, 0.98, 0.7),
m_LastDamage(0), m_ForwardDirection(0), m_LastDamage(0), m_ForwardDirection(0),
m_DamageTaken(0.0f), m_Material(a_Material), m_DamageTaken(0.0f), m_Material(a_Material),
m_RightPaddleUsed(false), m_LeftPaddleUsed(false) m_RightPaddleUsed(false), m_LeftPaddleUsed(false)

View File

@ -35,6 +35,8 @@ public:
CLASS_PROTODEF(cBoat) CLASS_PROTODEF(cBoat)
cBoat(Vector3d a_Pos, eMaterial a_Material);
// cEntity overrides: // cEntity overrides:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual void OnRightClicked(cPlayer & a_Player) override; virtual void OnRightClicked(cPlayer & a_Player) override;
@ -42,8 +44,6 @@ public:
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override; virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override;
cBoat(Vector3d a_Pos, eMaterial a_Material);
int GetLastDamage(void) const { return m_LastDamage; } int GetLastDamage(void) const { return m_LastDamage; }
int GetForwardDirection(void) const { return m_ForwardDirection; } int GetForwardDirection(void) const { return m_ForwardDirection; }

View File

@ -10,8 +10,8 @@
cEnderCrystal::cEnderCrystal(double a_X, double a_Y, double a_Z) cEnderCrystal::cEnderCrystal(Vector3d a_Pos):
: cEntity(etEnderCrystal, a_X, a_Y, a_Z, 1.0, 1.0) super(etEnderCrystal, a_Pos, 1.0, 1.0)
{ {
SetMaxHealth(5); SetMaxHealth(5);
} }

View File

@ -12,12 +12,13 @@ class cEnderCrystal :
public cEntity public cEntity
{ {
// tolua_end // tolua_end
typedef cEntity super; using super = cEntity;
public: public:
CLASS_PROTODEF(cEnderCrystal) CLASS_PROTODEF(cEnderCrystal)
cEnderCrystal(double a_X, double a_Y, double a_Z); cEnderCrystal(Vector3d a_Pos);
private: private:

View File

@ -32,7 +32,7 @@ static UInt32 GetNextUniqueID(void)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cEntity: // cEntity:
cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height): cEntity::cEntity(eEntityType a_EntityType, Vector3d a_Pos, double a_Width, double a_Height):
m_UniqueID(GetNextUniqueID()), m_UniqueID(GetNextUniqueID()),
m_Health(1), m_Health(1),
m_MaxHealth(1), m_MaxHealth(1),
@ -44,7 +44,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
m_bOnGround(false), m_bOnGround(false),
m_Gravity(-9.81f), m_Gravity(-9.81f),
m_AirDrag(0.02f), m_AirDrag(0.02f),
m_LastPosition(a_X, a_Y, a_Z), m_LastPosition(a_Pos),
m_EntityType(a_EntityType), m_EntityType(a_EntityType),
m_World(nullptr), m_World(nullptr),
m_IsWorldChangeScheduled(false), m_IsWorldChangeScheduled(false),
@ -65,8 +65,8 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
m_ParentChunk(nullptr), m_ParentChunk(nullptr),
m_HeadYaw(0.0), m_HeadYaw(0.0),
m_Rot(0.0, 0.0, 0.0), m_Rot(0.0, 0.0, 0.0),
m_Position(a_X, a_Y, a_Z), m_Position(a_Pos),
m_LastSentPosition(a_X, a_Y, a_Z), m_LastSentPosition(a_Pos),
m_WaterSpeed(0, 0, 0), m_WaterSpeed(0, 0, 0),
m_Mass (0.001), // Default 1g m_Mass (0.001), // Default 1g
m_Width(a_Width), m_Width(a_Width),

View File

@ -156,7 +156,7 @@ public:
static const UInt32 INVALID_ID = 0; // Exported to Lua in ManualBindings.cpp, ToLua doesn't parse initialized constants. static const UInt32 INVALID_ID = 0; // Exported to Lua in ManualBindings.cpp, ToLua doesn't parse initialized constants.
cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); cEntity(eEntityType a_EntityType, Vector3d a_Pos, double a_Width, double a_Height);
virtual ~cEntity(); virtual ~cEntity();
/** Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed). /** Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed).
@ -558,7 +558,9 @@ public:
@return exposure rate */ @return exposure rate */
virtual float GetExplosionExposureRate(Vector3d a_ExplosionPosition, float a_ExlosionPower); virtual float GetExplosionExposureRate(Vector3d a_ExplosionPosition, float a_ExlosionPower);
protected: protected:
/** Structure storing the portal delay timer and cooldown boolean */ /** Structure storing the portal delay timer and cooldown boolean */
struct sPortalCooldownData struct sPortalCooldownData
{ {
@ -570,6 +572,7 @@ protected:
bool m_ShouldPreventTeleportation; bool m_ShouldPreventTeleportation;
}; };
/** Measured in meters / second (m / s) */ /** Measured in meters / second (m / s) */
Vector3d m_Speed; Vector3d m_Speed;
@ -686,6 +689,7 @@ protected:
Only to be used when the caller will broadcast a teleport or equivalent to clients. */ Only to be used when the caller will broadcast a teleport or equivalent to clients. */
virtual void ResetPosition(Vector3d a_NewPos); virtual void ResetPosition(Vector3d a_NewPos);
private: private:
/** Whether the entity is ticking or not. If not, it is scheduled for removal or world-teleportation. */ /** Whether the entity is ticking or not. If not, it is scheduled for removal or world-teleportation. */

View File

@ -8,18 +8,8 @@
cExpBottleEntity::cExpBottleEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, Vector3d a_Speed) :
super(pkExpBottle, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25)
{
SetSpeed(a_Speed);
}
cExpBottleEntity::cExpBottleEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed) : cExpBottleEntity::cExpBottleEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed) :
super(pkExpBottle, a_Creator, a_Pos.x, a_Pos.y, a_Pos.z, 0.25, 0.25) super(pkExpBottle, a_Creator, a_Pos, 0.25, 0.25)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);
} }

View File

@ -20,15 +20,13 @@
class cExpBottleEntity : class cExpBottleEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
CLASS_PROTODEF(cExpBottleEntity) using super = cProjectileEntity;
cExpBottleEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, Vector3d a_Speed); public: // tolua_export
CLASS_PROTODEF(cExpBottleEntity)
cExpBottleEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed); cExpBottleEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed);

View File

@ -5,25 +5,10 @@
#include "../ClientHandle.h" #include "../ClientHandle.h"
cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward) cExpOrb::cExpOrb(Vector3d a_Pos, int a_Reward):
: cEntity(etExpOrb, a_X, a_Y, a_Z, 0.98, 0.98) super(etExpOrb, a_Pos, 0.98, 0.98), // TODO: Check size
, m_Reward(a_Reward) m_Reward(a_Reward),
, m_Timer(0) m_Timer(0)
{
SetMaxHealth(5);
SetHealth(5);
SetGravity(-16);
SetAirDrag(0.02f);
}
cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward)
: cEntity(etExpOrb, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98)
, m_Reward(a_Reward)
, m_Timer(0)
{ {
SetMaxHealth(5); SetMaxHealth(5);
SetHealth(5); SetHealth(5);

View File

@ -18,8 +18,7 @@ public:
CLASS_PROTODEF(cExpOrb) CLASS_PROTODEF(cExpOrb)
cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward); cExpOrb(Vector3d a_Pos, int a_Reward);
cExpOrb(const Vector3d & a_Pos, int a_Reward);
// Override functions // Override functions
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;

View File

@ -10,8 +10,8 @@
cFallingBlock::cFallingBlock(const Vector3i & a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) : cFallingBlock::cFallingBlock(Vector3i a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) :
super(etFallingBlock, a_BlockPosition.x + 0.5f, a_BlockPosition.y, a_BlockPosition.z + 0.5f, 0.98, 0.98), super(etFallingBlock, Vector3d(0.5, 0, 0.5) + a_BlockPosition, 0.98, 0.98),
m_BlockType(a_BlockType), m_BlockType(a_BlockType),
m_BlockMeta(a_BlockMeta), m_BlockMeta(a_BlockMeta),
m_OriginalPosition(a_BlockPosition) m_OriginalPosition(a_BlockPosition)

View File

@ -8,19 +8,20 @@
// tolua_begin // tolua_begin
class cFallingBlock : class cFallingBlock :
public cEntity public cEntity
{ {
typedef cEntity super;
public:
// tolua_end // tolua_end
using super = cEntity;
public: // tolua_export
CLASS_PROTODEF(cFallingBlock) CLASS_PROTODEF(cFallingBlock)
/** Creates a new falling block. a_BlockPosition is expected in world coords */ /** Creates a new falling block.
cFallingBlock(const Vector3i & a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); a_BlockPosition is expected in world coords */
cFallingBlock(Vector3i a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
// tolua_begin // tolua_begin

View File

@ -7,8 +7,8 @@
cFireChargeEntity::cFireChargeEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : cFireChargeEntity::cFireChargeEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkFireCharge, a_Creator, a_X, a_Y, a_Z, 0.3125, 0.3125) super(pkFireCharge, a_Creator, a_Pos, 0.3125, 0.3125)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);
SetGravity(0); SetGravity(0);

View File

@ -20,15 +20,15 @@
class cFireChargeEntity : class cFireChargeEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
using super = cProjectileEntity;
public: // tolua_export
CLASS_PROTODEF(cFireChargeEntity) CLASS_PROTODEF(cFireChargeEntity)
cFireChargeEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); cFireChargeEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed);
protected: protected:

View File

@ -8,8 +8,8 @@
cFireworkEntity::cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item) : cFireworkEntity::cFireworkEntity(cEntity * a_Creator, Vector3d a_Pos, const cItem & a_Item) :
super(pkFirework, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25), super(pkFirework, a_Creator, a_Pos, 0.25, 0.25),
m_TicksToExplosion(a_Item.m_FireworkItem.m_FlightTimeInTicks), m_TicksToExplosion(a_Item.m_FireworkItem.m_FlightTimeInTicks),
m_FireworkItem(a_Item) m_FireworkItem(a_Item)
{ {

View File

@ -20,15 +20,15 @@
class cFireworkEntity : class cFireworkEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
using super = cProjectileEntity;
public: // tolua_export
CLASS_PROTODEF(cFireworkEntity) CLASS_PROTODEF(cFireworkEntity)
cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item); cFireworkEntity(cEntity * a_Creator, Vector3d a_Pos, const cItem & a_Item);
// tolua_begin // tolua_begin

View File

@ -73,9 +73,9 @@ protected:
cFloater::cFloater(double a_X, double a_Y, double a_Z, Vector3d a_Speed, UInt32 a_PlayerID, int a_CountDownTime) : cFloater::cFloater(Vector3d a_Pos, Vector3d a_Speed, UInt32 a_PlayerID, int a_CountDownTime) :
cEntity(etFloater, a_X, a_Y, a_Z, 0.2, 0.2), super(etFloater, a_Pos, 0.2, 0.2),
m_BitePos(Vector3d(a_X, a_Y, a_Z)), m_BitePos(a_Pos),
m_CanPickupItem(false), m_CanPickupItem(false),
m_PickupCountDown(0), m_PickupCountDown(0),
m_CountDownTime(a_CountDownTime), m_CountDownTime(a_CountDownTime),

View File

@ -11,14 +11,15 @@
class cFloater : class cFloater :
public cEntity public cEntity
{ {
typedef cEntity super;
public:
// tolua_end // tolua_end
using super = cEntity;
public: // tolua_export
CLASS_PROTODEF(cFloater) CLASS_PROTODEF(cFloater)
cFloater(double a_X, double a_Y, double a_Z, Vector3d a_Speed, UInt32 a_PlayerID, int a_CountDownTime); cFloater(Vector3d a_Pos, Vector3d a_Speed, UInt32 a_PlayerID, int a_CountDownTime);
virtual void SpawnOn(cClientHandle & a_Client) override; virtual void SpawnOn(cClientHandle & a_Client) override;
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;

View File

@ -7,8 +7,8 @@
cGhastFireballEntity::cGhastFireballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : cGhastFireballEntity::cGhastFireballEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkGhastFireball, a_Creator, a_X, a_Y, a_Z, 1, 1) super(pkGhastFireball, a_Creator, a_Pos, 1, 1)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);
SetGravity(0); SetGravity(0);

View File

@ -20,15 +20,15 @@
class cGhastFireballEntity : class cGhastFireballEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
using super = cProjectileEntity;
public: // tolua_export
CLASS_PROTODEF(cGhastFireballEntity) CLASS_PROTODEF(cGhastFireballEntity)
cGhastFireballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); cGhastFireballEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed);
protected: protected:

View File

@ -9,8 +9,8 @@
cHangingEntity::cHangingEntity(eEntityType a_EntityType, eBlockFace a_Facing, double a_X, double a_Y, double a_Z) : cHangingEntity::cHangingEntity(eEntityType a_EntityType, eBlockFace a_Facing, Vector3d a_Pos) :
cEntity(a_EntityType, a_X, a_Y, a_Z, 0.8, 0.8), super(a_EntityType, a_Pos, 0.8, 0.8),
m_Facing(cHangingEntity::BlockFaceToProtocolFace(a_Facing)) m_Facing(cHangingEntity::BlockFaceToProtocolFace(a_Facing))
{ {
SetMaxHealth(1); SetMaxHealth(1);

View File

@ -11,15 +11,15 @@
class cHangingEntity : class cHangingEntity :
public cEntity public cEntity
{ {
typedef cEntity super;
public:
// tolua_end // tolua_end
using super = cEntity;
public: // tolua_export
CLASS_PROTODEF(cHangingEntity) CLASS_PROTODEF(cHangingEntity)
cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z); cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, Vector3d a_Pos);
// tolua_begin // tolua_begin

View File

@ -9,8 +9,8 @@
cItemFrame::cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z) : cItemFrame::cItemFrame(eBlockFace a_BlockFace, Vector3d a_Pos):
cHangingEntity(etItemFrame, a_BlockFace, a_X, a_Y, a_Z), super(etItemFrame, a_BlockFace, a_Pos),
m_Item(E_BLOCK_AIR), m_Item(E_BLOCK_AIR),
m_ItemRotation(0) m_ItemRotation(0)
{ {

View File

@ -11,15 +11,15 @@
class cItemFrame : class cItemFrame :
public cHangingEntity public cHangingEntity
{ {
typedef cHangingEntity super;
public:
// tolua_end // tolua_end
using super = cHangingEntity;
public: // tolua_export
CLASS_PROTODEF(cItemFrame) CLASS_PROTODEF(cItemFrame)
cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z); cItemFrame(eBlockFace a_BlockFace, Vector3d a_Pos);
// tolua_begin // tolua_begin

View File

@ -14,8 +14,8 @@
cLeashKnot::cLeashKnot(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z) : cLeashKnot::cLeashKnot(eBlockFace a_BlockFace, Vector3d a_Pos) :
cHangingEntity(etLeashKnot, a_BlockFace, a_X, a_Y, a_Z), super(etLeashKnot, a_BlockFace, a_Pos),
m_ShouldSelfDestroy(false), m_ShouldSelfDestroy(false),
m_TicksToSelfDestroy(20 * 1) m_TicksToSelfDestroy(20 * 1)
{ {

View File

@ -13,15 +13,14 @@ class cWorldInterface;
class cLeashKnot : class cLeashKnot :
public cHangingEntity public cHangingEntity
{ {
typedef cHangingEntity super;
public:
// tolua_end // tolua_end
using super = cHangingEntity;
public: // tolua_export
CLASS_PROTODEF(cLeashKnot) CLASS_PROTODEF(cLeashKnot)
cLeashKnot(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z); cLeashKnot(eBlockFace a_BlockFace, Vector3d a_Pos);
/** Looks for mobs leashed to a player and ties them to this knot */ /** Looks for mobs leashed to a player and ties them to this knot */
void TiePlayersLeashedMobs(cPlayer & a_Player, bool a_ShouldBroadCast); void TiePlayersLeashedMobs(cPlayer & a_Player, bool a_ShouldBroadCast);

View File

@ -90,8 +90,11 @@ protected:
cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) : ////////////////////////////////////////////////////////////////////////////////
super(etMinecart, a_X, a_Y, a_Z, 0.98, 0.7), // cMinecart:
cMinecart::cMinecart(ePayload a_Payload, Vector3d a_Pos):
super(etMinecart, a_Pos, 0.98, 0.7),
m_Payload(a_Payload), m_Payload(a_Payload),
m_LastDamage(0), m_LastDamage(0),
m_DetectorRailPosition(0, 0, 0), m_DetectorRailPosition(0, 0, 0),
@ -1164,8 +1167,8 @@ void cMinecart::Destroyed()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cRideableMinecart: // cRideableMinecart:
cRideableMinecart::cRideableMinecart(double a_X, double a_Y, double a_Z, const cItem & a_Content, int a_Height) : cRideableMinecart::cRideableMinecart(Vector3d a_Pos, const cItem & a_Content, int a_Height):
super(mpNone, a_X, a_Y, a_Z), super(mpNone, a_Pos),
m_Content(a_Content), m_Content(a_Content),
m_Height(a_Height) m_Height(a_Height)
{ {
@ -1209,8 +1212,8 @@ void cRideableMinecart::OnRightClicked(cPlayer & a_Player)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cMinecartWithChest: // cMinecartWithChest:
cMinecartWithChest::cMinecartWithChest(double a_X, double a_Y, double a_Z) : cMinecartWithChest::cMinecartWithChest(Vector3d a_Pos):
super(mpChest, a_X, a_Y, a_Z), super(mpChest, a_Pos),
cEntityWindowOwner(this), cEntityWindowOwner(this),
m_Contents(ContentsWidth, ContentsHeight) m_Contents(ContentsWidth, ContentsHeight)
{ {
@ -1283,8 +1286,8 @@ void cMinecartWithChest::Destroyed()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cMinecartWithFurnace: // cMinecartWithFurnace:
cMinecartWithFurnace::cMinecartWithFurnace(double a_X, double a_Y, double a_Z) : cMinecartWithFurnace::cMinecartWithFurnace(Vector3d a_Pos):
super(mpFurnace, a_X, a_Y, a_Z), super(mpFurnace, a_Pos),
m_FueledTimeLeft(-1), m_FueledTimeLeft(-1),
m_IsFueled(false) m_IsFueled(false)
{ {
@ -1350,8 +1353,8 @@ void cMinecartWithFurnace::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cMinecartWithTNT: // cMinecartWithTNT:
cMinecartWithTNT::cMinecartWithTNT(double a_X, double a_Y, double a_Z) : cMinecartWithTNT::cMinecartWithTNT(Vector3d a_Pos):
super(mpTNT, a_X, a_Y, a_Z) super(mpTNT, a_Pos)
{ {
} }
@ -1364,8 +1367,8 @@ cMinecartWithTNT::cMinecartWithTNT(double a_X, double a_Y, double a_Z) :
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cMinecartWithHopper: // cMinecartWithHopper:
cMinecartWithHopper::cMinecartWithHopper(double a_X, double a_Y, double a_Z) : cMinecartWithHopper::cMinecartWithHopper(Vector3d a_Pos):
super(mpHopper, a_X, a_Y, a_Z) super(mpHopper, a_Pos)
{ {
} }

View File

@ -20,7 +20,7 @@
class cMinecart : class cMinecart :
public cEntity public cEntity
{ {
typedef cEntity super; using super = cEntity;
public: public:
CLASS_PROTODEF(cMinecart) CLASS_PROTODEF(cMinecart)
@ -45,7 +45,9 @@ public:
int LastDamage(void) const { return m_LastDamage; } int LastDamage(void) const { return m_LastDamage; }
ePayload GetPayload(void) const { return m_Payload; } ePayload GetPayload(void) const { return m_Payload; }
protected: protected:
ePayload m_Payload; ePayload m_Payload;
int m_LastDamage; int m_LastDamage;
Vector3i m_DetectorRailPosition; Vector3i m_DetectorRailPosition;
@ -57,7 +59,7 @@ protected:
// Overwrite to enforce speed limit // Overwrite to enforce speed limit
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override; virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override;
cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z); cMinecart(ePayload a_Payload, Vector3d a_Pos);
/** Handles physics on normal rails /** Handles physics on normal rails
For each tick, slow down on flat rails, speed up or slow down on ascending / descending rails (depending on direction), and turn on curved rails. */ For each tick, slow down on flat rails, speed up or slow down on ascending / descending rails (depending on direction), and turn on curved rails. */
@ -95,19 +97,23 @@ protected:
class cRideableMinecart : class cRideableMinecart :
public cMinecart public cMinecart
{ {
typedef cMinecart super; using super = cMinecart;
public: public:
CLASS_PROTODEF(cRideableMinecart) CLASS_PROTODEF(cRideableMinecart)
cRideableMinecart(double a_X, double a_Y, double a_Z, const cItem & a_Content, int a_Height); cRideableMinecart(Vector3d a_Pos, const cItem & a_Content, int a_Height);
const cItem & GetContent(void) const {return m_Content;} const cItem & GetContent(void) const {return m_Content;}
int GetBlockHeight(void) const {return m_Height;} int GetBlockHeight(void) const {return m_Height;}
// cEntity overrides: // cEntity overrides:
virtual void OnRightClicked(cPlayer & a_Player) override; virtual void OnRightClicked(cPlayer & a_Player) override;
protected: protected:
cItem m_Content; cItem m_Content;
int m_Height; int m_Height;
} ; } ;
@ -121,12 +127,13 @@ class cMinecartWithChest :
public cItemGrid::cListener, public cItemGrid::cListener,
public cEntityWindowOwner public cEntityWindowOwner
{ {
typedef cMinecart super; using super = cMinecart;
public: public:
CLASS_PROTODEF(cMinecartWithChest) CLASS_PROTODEF(cMinecartWithChest)
cMinecartWithChest(double a_X, double a_Y, double a_Z); cMinecartWithChest(Vector3d a_Pos);
enum enum
{ {
@ -137,7 +144,9 @@ public:
const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); } const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); }
void SetSlot(int a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); } void SetSlot(int a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); }
protected: protected:
cItemGrid m_Contents; cItemGrid m_Contents;
void OpenNewWindow(void); void OpenNewWindow(void);
virtual void Destroyed() override; virtual void Destroyed() override;
@ -169,12 +178,13 @@ protected:
class cMinecartWithFurnace : class cMinecartWithFurnace :
public cMinecart public cMinecart
{ {
typedef cMinecart super; using super = cMinecart;
public: public:
CLASS_PROTODEF(cMinecartWithFurnace) CLASS_PROTODEF(cMinecartWithFurnace)
cMinecartWithFurnace(double a_X, double a_Y, double a_Z); cMinecartWithFurnace(Vector3d a_Pos);
// cEntity overrides: // cEntity overrides:
virtual void OnRightClicked(cPlayer & a_Player) override; virtual void OnRightClicked(cPlayer & a_Player) override;
@ -201,12 +211,12 @@ private:
class cMinecartWithTNT : class cMinecartWithTNT :
public cMinecart public cMinecart
{ {
typedef cMinecart super; using super = cMinecart;
public: public:
CLASS_PROTODEF(cMinecartWithTNT) CLASS_PROTODEF(cMinecartWithTNT)
cMinecartWithTNT(double a_X, double a_Y, double a_Z); cMinecartWithTNT(Vector3d a_Pos);
} ; } ;
@ -216,10 +226,11 @@ public:
class cMinecartWithHopper : class cMinecartWithHopper :
public cMinecart public cMinecart
{ {
typedef cMinecart super; using super = cMinecart;
public: public:
CLASS_PROTODEF(cMinecartWithHopper) CLASS_PROTODEF(cMinecartWithHopper)
cMinecartWithHopper(double a_X, double a_Y, double a_Z); cMinecartWithHopper(Vector3d a_Pos);
} ; } ;

View File

@ -10,8 +10,8 @@
cPainting::cPainting(const AString & a_Name, eBlockFace a_Direction, double a_X, double a_Y, double a_Z) cPainting::cPainting(const AString & a_Name, eBlockFace a_Direction, Vector3d a_Pos):
: cHangingEntity(etPainting, a_Direction, a_X, a_Y, a_Z), super(etPainting, a_Direction, a_Pos),
m_Name(a_Name) m_Name(a_Name)
{ {
} }

View File

@ -11,15 +11,15 @@
class cPainting : class cPainting :
public cHangingEntity public cHangingEntity
{ {
typedef cHangingEntity super;
public:
// tolua_end // tolua_end
using super = cHangingEntity;
public: // tolua_export
CLASS_PROTODEF(cPainting) CLASS_PROTODEF(cPainting)
cPainting(const AString & a_Name, eBlockFace a_Direction, double a_X, double a_Y, double a_Z); cPainting(const AString & a_Name, eBlockFace a_Direction, Vector3d a_Pos);
/** Returns the protocol name of the painting */ /** Returns the protocol name of the painting */
const AString & GetName(void) const { return m_Name; } // tolua_export const AString & GetName(void) const { return m_Name; } // tolua_export

View File

@ -14,7 +14,7 @@
cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height) : cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height) :
super(a_EntityType, 0, 0, 0, a_Width, a_Height), super(a_EntityType, Vector3d(), a_Width, a_Height),
m_EntityEffects(tEffectMap()), m_EntityEffects(tEffectMap()),
m_LastGroundHeight(0), m_LastGroundHeight(0),
m_bTouchGround(false) m_bTouchGround(false)

View File

@ -93,20 +93,23 @@ protected:
cPickup::cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX, float a_SpeedY, float a_SpeedZ, int a_LifetimeTicks, bool a_CanCombine) ////////////////////////////////////////////////////////////////////////////////
: cEntity(etPickup, a_PosX, a_PosY, a_PosZ, 0.2, 0.2) // cPickup:
, m_Timer(0)
, m_Item(a_Item) cPickup::cPickup(Vector3d a_Pos, const cItem & a_Item, bool IsPlayerCreated, Vector3f a_Speed, int a_LifetimeTicks, bool a_CanCombine):
, m_bCollected(false) super(etPickup, a_Pos, 0.2, 0.2),
, m_bIsPlayerCreated(IsPlayerCreated) m_Timer(0),
, m_bCanCombine(a_CanCombine) m_Item(a_Item),
, m_Lifetime(cTickTime(a_LifetimeTicks)) m_bCollected(false),
m_bIsPlayerCreated(IsPlayerCreated),
m_bCanCombine(a_CanCombine),
m_Lifetime(cTickTime(a_LifetimeTicks))
{ {
SetGravity(-16.0f); SetGravity(-16.0f);
SetAirDrag(0.02f); SetAirDrag(0.02f);
SetMaxHealth(5); SetMaxHealth(5);
SetHealth(5); SetHealth(5);
SetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ); SetSpeed(a_Speed);
} }

View File

@ -18,14 +18,15 @@ class cPlayer;
class cPickup : class cPickup :
public cEntity public cEntity
{ {
typedef cEntity super;
public:
// tolua_end // tolua_end
using super = cEntity;
public: // tolua_export
CLASS_PROTODEF(cPickup) CLASS_PROTODEF(cPickup)
cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f, int a_LifetimeTicks = 6000, bool a_CanCombine = true); cPickup(Vector3d a_Pos, const cItem & a_Item, bool IsPlayerCreated, Vector3f a_Speed = Vector3f(), int a_LifetimeTicks = 6000, bool a_CanCombine = true);
cItem & GetItem(void) {return m_Item; } // tolua_export cItem & GetItem(void) {return m_Item; } // tolua_export
const cItem & GetItem(void) const {return m_Item; } const cItem & GetItem(void) const {return m_Item; }

View File

@ -224,8 +224,8 @@ protected:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cProjectileEntity: // cProjectileEntity:
cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height) : cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, Vector3d a_Pos, double a_Width, double a_Height):
super(etProjectile, a_X, a_Y, a_Z, a_Width, a_Height), super(etProjectile, a_Pos, a_Width, a_Height),
m_ProjectileKind(a_Kind), m_ProjectileKind(a_Kind),
m_CreatorData( m_CreatorData(
((a_Creator != nullptr) ? a_Creator->GetUniqueID() : cEntity::INVALID_ID), ((a_Creator != nullptr) ? a_Creator->GetUniqueID() : cEntity::INVALID_ID),
@ -242,8 +242,8 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a
cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height) : cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed, double a_Width, double a_Height):
super(etProjectile, a_Pos.x, a_Pos.y, a_Pos.z, a_Width, a_Height), super(etProjectile, a_Pos, a_Width, a_Height),
m_ProjectileKind(a_Kind), m_ProjectileKind(a_Kind),
m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? static_cast<cPlayer *>(a_Creator)->GetName() : "", a_Creator->GetEquippedWeapon().m_Enchantments), m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? static_cast<cPlayer *>(a_Creator)->GetName() : "", a_Creator->GetEquippedWeapon().m_Enchantments),
m_IsInGround(false) m_IsInGround(false)
@ -259,7 +259,13 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Ve
std::unique_ptr<cProjectileEntity> cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed) std::unique_ptr<cProjectileEntity> cProjectileEntity::Create(
eKind a_Kind,
cEntity * a_Creator,
Vector3d a_Pos,
const cItem * a_Item,
const Vector3d * a_Speed
)
{ {
Vector3d Speed; Vector3d Speed;
if (a_Speed != nullptr) if (a_Speed != nullptr)
@ -269,15 +275,15 @@ std::unique_ptr<cProjectileEntity> cProjectileEntity::Create(eKind a_Kind, cEnti
switch (a_Kind) switch (a_Kind)
{ {
case pkArrow: return cpp14::make_unique<cArrowEntity> (a_Creator, a_X, a_Y, a_Z, Speed); case pkArrow: return cpp14::make_unique<cArrowEntity> (a_Creator, a_Pos, Speed);
case pkEgg: return cpp14::make_unique<cThrownEggEntity> (a_Creator, a_X, a_Y, a_Z, Speed); case pkEgg: return cpp14::make_unique<cThrownEggEntity> (a_Creator, a_Pos, Speed);
case pkEnderPearl: return cpp14::make_unique<cThrownEnderPearlEntity>(a_Creator, a_X, a_Y, a_Z, Speed); case pkEnderPearl: return cpp14::make_unique<cThrownEnderPearlEntity>(a_Creator, a_Pos, Speed);
case pkSnowball: return cpp14::make_unique<cThrownSnowballEntity> (a_Creator, a_X, a_Y, a_Z, Speed); case pkSnowball: return cpp14::make_unique<cThrownSnowballEntity> (a_Creator, a_Pos, Speed);
case pkGhastFireball: return cpp14::make_unique<cGhastFireballEntity> (a_Creator, a_X, a_Y, a_Z, Speed); case pkGhastFireball: return cpp14::make_unique<cGhastFireballEntity> (a_Creator, a_Pos, Speed);
case pkFireCharge: return cpp14::make_unique<cFireChargeEntity> (a_Creator, a_X, a_Y, a_Z, Speed); case pkFireCharge: return cpp14::make_unique<cFireChargeEntity> (a_Creator, a_Pos, Speed);
case pkExpBottle: return cpp14::make_unique<cExpBottleEntity> (a_Creator, a_X, a_Y, a_Z, Speed); case pkExpBottle: return cpp14::make_unique<cExpBottleEntity> (a_Creator, a_Pos, Speed);
case pkSplashPotion: return cpp14::make_unique<cSplashPotionEntity> (a_Creator, a_X, a_Y, a_Z, Speed, *a_Item); case pkSplashPotion: return cpp14::make_unique<cSplashPotionEntity> (a_Creator, a_Pos, Speed, *a_Item);
case pkWitherSkull: return cpp14::make_unique<cWitherSkullEntity> (a_Creator, a_X, a_Y, a_Z, Speed); case pkWitherSkull: return cpp14::make_unique<cWitherSkullEntity> (a_Creator, a_Pos, Speed);
case pkFirework: case pkFirework:
{ {
ASSERT(a_Item != nullptr); ASSERT(a_Item != nullptr);
@ -286,7 +292,7 @@ std::unique_ptr<cProjectileEntity> cProjectileEntity::Create(eKind a_Kind, cEnti
return nullptr; return nullptr;
} }
return cpp14::make_unique<cFireworkEntity>(a_Creator, a_X, a_Y, a_Z, *a_Item); return cpp14::make_unique<cFireworkEntity>(a_Creator, a_Pos, *a_Item);
} }
case pkFishingFloat: break; case pkFishingFloat: break;
} }

View File

@ -20,9 +20,15 @@
class cProjectileEntity : class cProjectileEntity :
public cEntity public cEntity
{ {
typedef cEntity super; // tolua_end
using super = cEntity;
// tolua_begin
public: public:
/** The kind of the projectile. The numbers correspond to the network type ID used for spawning them in the protocol. */ /** The kind of the projectile. The numbers correspond to the network type ID used for spawning them in the protocol. */
enum eKind enum eKind
{ {
@ -43,10 +49,32 @@ public:
CLASS_PROTODEF(cProjectileEntity) CLASS_PROTODEF(cProjectileEntity)
cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); cProjectileEntity(eKind a_Kind, cEntity * a_Creator, Vector3d a_Pos, double a_Width, double a_Height);
cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height); cProjectileEntity(eKind a_Kind, cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed, double a_Width, double a_Height);
static std::unique_ptr<cProjectileEntity> Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed = nullptr); /** Creates a new instance of the specified projectile entity.
a_Item is the item from which the projectile originated (such as firework or arrow). */
static std::unique_ptr<cProjectileEntity> Create(
eKind a_Kind,
cEntity * a_Creator,
Vector3d a_Pos,
const cItem * a_Item,
const Vector3d * a_Speed = nullptr
);
/** OBSOLETE, use the Vector3d-based overload instead.
Creates a new instance of the specified projectile entity.
a_Item is the item from which the projectile originated (such as firework or arrow). */
static std::unique_ptr<cProjectileEntity> Create(
eKind a_Kind,
cEntity * a_Creator,
double a_PosX, double a_PosY, double a_PosZ,
const cItem * a_Item,
const Vector3d * a_Speed = nullptr
)
{
return Create(a_Kind, a_Creator, {a_PosX, a_PosY, a_PosZ}, a_Item, a_Speed);
}
/** Called by the physics blocktracer when the entity hits a solid block, the hit position and the face hit (BLOCK_FACE_) is given */ /** Called by the physics blocktracer when the entity hits a solid block, the hit position and the face hit (BLOCK_FACE_) is given */
virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace); virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace);

View File

@ -21,11 +21,11 @@
cSplashPotionEntity::cSplashPotionEntity( cSplashPotionEntity::cSplashPotionEntity(
cEntity * a_Creator, cEntity * a_Creator,
double a_X, double a_Y, double a_Z, Vector3d a_Pos,
const Vector3d & a_Speed, Vector3d a_Speed,
const cItem & a_Item const cItem & a_Item
) : ):
super(pkSplashPotion, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25), super(pkSplashPotion, a_Creator, a_Pos, 0.25, 0.25),
m_Item(a_Item), m_Item(a_Item),
m_DestroyTimer(-1) m_DestroyTimer(-1)
{ {

View File

@ -24,18 +24,18 @@ class cEntity;
class cSplashPotionEntity : class cSplashPotionEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
using super = cProjectileEntity;
public: // tolua_export
CLASS_PROTODEF(cSplashPotionEntity) CLASS_PROTODEF(cSplashPotionEntity)
cSplashPotionEntity( cSplashPotionEntity(
cEntity * a_Creator, cEntity * a_Creator,
double a_X, double a_Y, double a_Z, Vector3d a_Pos,
const Vector3d & a_Speed, Vector3d a_Speed,
const cItem & a_Item const cItem & a_Item
); );

View File

@ -9,7 +9,7 @@
cTNTEntity::cTNTEntity(Vector3d a_Pos, int a_FuseTicks) : cTNTEntity::cTNTEntity(Vector3d a_Pos, int a_FuseTicks) :
super(etTNT, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98), super(etTNT, a_Pos, 0.98, 0.98),
m_FuseTicks(a_FuseTicks) m_FuseTicks(a_FuseTicks)
{ {
SetGravity(-16.0f); SetGravity(-16.0f);

View File

@ -7,8 +7,8 @@
cThrownEggEntity::cThrownEggEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : cThrownEggEntity::cThrownEggEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkEgg, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25), super(pkEgg, a_Creator, a_Pos, 0.25, 0.25),
m_DestroyTimer(-1) m_DestroyTimer(-1)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);

View File

@ -20,15 +20,15 @@
class cThrownEggEntity : class cThrownEggEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
using super = cProjectileEntity;
public: // tolua_export
CLASS_PROTODEF(cThrownEggEntity) CLASS_PROTODEF(cThrownEggEntity)
cThrownEggEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); cThrownEggEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed);
protected: protected:

View File

@ -8,8 +8,8 @@
cThrownEnderPearlEntity::cThrownEnderPearlEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : cThrownEnderPearlEntity::cThrownEnderPearlEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkEnderPearl, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25), super(pkEnderPearl, a_Creator, a_Pos, 0.25, 0.25),
m_DestroyTimer(-1) m_DestroyTimer(-1)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);

View File

@ -20,15 +20,15 @@
class cThrownEnderPearlEntity : class cThrownEnderPearlEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
using super = cProjectileEntity;
public: // tolua_export
CLASS_PROTODEF(cThrownEnderPearlEntity) CLASS_PROTODEF(cThrownEnderPearlEntity)
cThrownEnderPearlEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); cThrownEnderPearlEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed);
protected: protected:

View File

@ -7,8 +7,8 @@
cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkSnowball, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25), super(pkSnowball, a_Creator, a_Pos, 0.25, 0.25),
m_DestroyTimer(-1) m_DestroyTimer(-1)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);

View File

@ -20,15 +20,15 @@
class cThrownSnowballEntity : class cThrownSnowballEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
using super = cProjectileEntity;
public: // tolua_export
CLASS_PROTODEF(cThrownSnowballEntity) CLASS_PROTODEF(cThrownSnowballEntity)
cThrownSnowballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); cThrownSnowballEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed);
protected: protected:

View File

@ -12,8 +12,8 @@
cWitherSkullEntity::cWitherSkullEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : cWitherSkullEntity::cWitherSkullEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkWitherSkull, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25) super(pkWitherSkull, a_Creator, a_Pos, 0.25, 0.25)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);
SetGravity(0); SetGravity(0);

View File

@ -20,15 +20,15 @@
class cWitherSkullEntity : class cWitherSkullEntity :
public cProjectileEntity public cProjectileEntity
{ {
typedef cProjectileEntity super;
public:
// tolua_end // tolua_end
using super = cProjectileEntity;
public: // tolua_export
CLASS_PROTODEF(cWitherSkullEntity) CLASS_PROTODEF(cWitherSkullEntity)
cWitherSkullEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); cWitherSkullEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed);
protected: protected:

View File

@ -595,7 +595,7 @@ cBlockEntity * cChunkDesc::GetBlockEntity(int a_RelX, int a_RelY, int a_RelZ)
int AbsZ = a_RelZ + m_Coords.m_ChunkZ * cChunkDef::Width; int AbsZ = a_RelZ + m_Coords.m_ChunkZ * cChunkDef::Width;
// The block entity is not created yet, try to create it and add to list: // The block entity is not created yet, try to create it and add to list:
cBlockEntity * be = cBlockEntity::CreateByBlockType(GetBlockType(a_RelX, a_RelY, a_RelZ), GetBlockMeta(a_RelX, a_RelY, a_RelZ), AbsX, a_RelY, AbsZ); cBlockEntity * be = cBlockEntity::CreateByBlockType(GetBlockType(a_RelX, a_RelY, a_RelZ), GetBlockMeta(a_RelX, a_RelY, a_RelZ), {AbsX, a_RelY, AbsZ});
if (be == nullptr) if (be == nullptr)
{ {
// No block entity for this block type // No block entity for this block type

View File

@ -228,9 +228,9 @@ public:
FloaterPos.y += 0.5f; FloaterPos.y += 0.5f;
const float FISH_SPEED_MULT = 2.25f; const float FISH_SPEED_MULT = 2.25f;
Vector3d FlyDirection = a_Player->GetEyePosition() - FloaterPos; Vector3d FlyDirection = (a_Player->GetEyePosition() - FloaterPos).addedY(1.0f) * FISH_SPEED_MULT;
a_World->SpawnItemPickups(Drops, FloaterPos.x, FloaterPos.y, FloaterPos.z, FlyDirection.x * FISH_SPEED_MULT, (FlyDirection.y + 1.0f) * FISH_SPEED_MULT, FlyDirection.z * FISH_SPEED_MULT); a_World->SpawnItemPickups(Drops, FloaterPos, FlyDirection);
a_World->SpawnExperienceOrb(a_Player->GetPosX(), a_Player->GetPosY(), a_Player->GetPosZ(), Random.RandInt(1, 6)); a_World->SpawnExperienceOrb(a_Player->GetPosition(), Random.RandInt(1, 6));
a_Player->UseEquippedItem(1); a_Player->UseEquippedItem(1);
cRoot::Get()->GetPluginManager()->CallHookPlayerFished(*a_Player, Drops); cRoot::Get()->GetPluginManager()->CallHookPlayerFished(*a_Player, Drops);
} }
@ -245,7 +245,7 @@ public:
} }
else else
{ {
auto Floater = cpp14::make_unique<cFloater>(a_Player->GetPosX(), a_Player->GetStance(), a_Player->GetPosZ(), a_Player->GetLookVector() * 15, a_Player->GetUniqueID(), (Random.RandInt(100, 900) - static_cast<int>(a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLure) * 100))); auto Floater = cpp14::make_unique<cFloater>(a_Player->GetEyePosition(), a_Player->GetLookVector() * 15, a_Player->GetUniqueID(), (Random.RandInt(100, 900) - static_cast<int>(a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLure) * 100)));
auto FloaterPtr = Floater.get(); auto FloaterPtr = Floater.get();
if (!FloaterPtr->Initialize(std::move(Floater), *a_World)) if (!FloaterPtr->Initialize(std::move(Floater), *a_World))
{ {

View File

@ -38,7 +38,7 @@ public:
if (Block == E_BLOCK_AIR) if (Block == E_BLOCK_AIR)
{ {
auto ItemFrame = cpp14::make_unique<cItemFrame>(a_BlockFace, a_BlockX, a_BlockY, a_BlockZ); auto ItemFrame = cpp14::make_unique<cItemFrame>(a_BlockFace, Vector3i{a_BlockX, a_BlockY, a_BlockZ});
auto ItemFramePtr = ItemFrame.get(); auto ItemFramePtr = ItemFrame.get();
if (!ItemFramePtr->Initialize(std::move(ItemFrame), *a_World)) if (!ItemFramePtr->Initialize(std::move(ItemFrame), *a_World))
{ {

View File

@ -70,7 +70,7 @@ public:
{ "BurningSkull" } { "BurningSkull" }
}; };
auto Painting = cpp14::make_unique<cPainting>(gPaintingTitlesList[a_World->GetTickRandomNumber(ARRAYCOUNT(gPaintingTitlesList) - 1)].Title, a_BlockFace, a_BlockX, a_BlockY, a_BlockZ); auto Painting = cpp14::make_unique<cPainting>(gPaintingTitlesList[a_World->GetTickRandomNumber(ARRAYCOUNT(gPaintingTitlesList) - 1)].Title, a_BlockFace, Vector3i{a_BlockX, a_BlockY, a_BlockZ});
auto PaintingPtr = Painting.get(); auto PaintingPtr = Painting.get();
if (!PaintingPtr->Initialize(std::move(Painting), *a_World)) if (!PaintingPtr->Initialize(std::move(Painting), *a_World))
{ {

View File

@ -40,7 +40,7 @@ bool cBlaze::Attack(std::chrono::milliseconds a_Dt)
Vector3d Speed = GetLookVector() * 20; Vector3d Speed = GetLookVector() * 20;
Speed.y = Speed.y + 1; Speed.y = Speed.y + 1;
auto FireCharge = cpp14::make_unique<cFireChargeEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); auto FireCharge = cpp14::make_unique<cFireChargeEntity>(this, GetPosition().addedY(1), Speed);
auto FireChargePtr = FireCharge.get(); auto FireChargePtr = FireCharge.get();
if (!FireChargePtr->Initialize(std::move(FireCharge), *m_World)) if (!FireChargePtr->Initialize(std::move(FireCharge), *m_World))
{ {

Some files were not shown because too many files have changed in this diff Show More