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",
},
GetRelPos =
{
Returns =
{
{
Type = "Vector3i",
},
},
Notes = "Returns the relative coords of the block entity's block within its chunk",
},
GetRelX =
{
Returns =

View File

@ -1150,6 +1150,78 @@ end
{
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 =
{
Params =
@ -1643,6 +1715,78 @@ end
{
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 =
{
Params =
@ -2168,6 +2312,78 @@ end
{
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 =
{
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));
int a_OutputX, a_OutputY, a_OutputZ;
bool res = self->GetOutputBlockPos(a_BlockMeta, a_OutputX, a_OutputY, a_OutputZ);
tolua_pushboolean(tolua_S, res);
if (res)
auto res = self->GetOutputBlockPos(a_BlockMeta);
tolua_pushboolean(tolua_S, res.first);
if (res.first)
{
tolua_pushnumber(tolua_S, static_cast<lua_Number>(a_OutputX));
tolua_pushnumber(tolua_S, static_cast<lua_Number>(a_OutputY));
tolua_pushnumber(tolua_S, static_cast<lua_Number>(a_OutputZ));
tolua_pushnumber(tolua_S, static_cast<lua_Number>(res.second.x));
tolua_pushnumber(tolua_S, static_cast<lua_Number>(res.second.y));
tolua_pushnumber(tolua_S, static_cast<lua_Number>(res.second.z));
return 4;
}
return 1;

View File

@ -572,7 +572,7 @@ void cBlockArea::CopyTo(cBlockArea & a_Into) const
for (const auto & keyPair: *m_BlockEntities)
{
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;
posY -= a_AddMinY;
posZ -= a_AddMinZ;
be->SetPos(posX, posY, posZ);
be->SetPos({posX, posY, posZ});
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 posY = be->GetPosY() + a_SubMinY;
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)});
}
}
@ -1097,7 +1097,7 @@ void cBlockArea::RotateCCW(void)
auto newY = be->GetPosY();
auto newZ = m_Size.x - be->GetPosX() - 1;
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)});
}
}
@ -1157,7 +1157,7 @@ void cBlockArea::RotateCW(void)
auto newY = be->GetPosY();
auto newZ = be->GetPosX();
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)});
}
}
@ -1216,7 +1216,7 @@ void cBlockArea::MirrorXY(void)
auto newY = be->GetPosY();
auto newZ = MaxZ - be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ);
be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)});
}
}
@ -1273,7 +1273,7 @@ void cBlockArea::MirrorXZ(void)
auto newY = MaxY - be->GetPosY();
auto newZ = be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ);
be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)});
}
}
@ -1330,7 +1330,7 @@ void cBlockArea::MirrorYZ(void)
auto newY = be->GetPosY();
auto newZ = be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ);
be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)});
}
}
@ -1389,7 +1389,7 @@ void cBlockArea::RotateCCWNoMeta(void)
auto newY = be->GetPosY();
auto newZ = m_Size.x - be->GetPosX() - 1;
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)});
}
}
@ -1450,7 +1450,7 @@ void cBlockArea::RotateCWNoMeta(void)
auto newY = be->GetPosY();
auto newZ = be->GetPosX();
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)});
}
}
@ -1506,7 +1506,7 @@ void cBlockArea::MirrorXYNoMeta(void)
auto newY = be->GetPosY();
auto newZ = MaxZ - be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ);
be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)});
}
}
@ -1560,7 +1560,7 @@ void cBlockArea::MirrorXZNoMeta(void)
auto newY = MaxY - be->GetPosY();
auto newZ = be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ);
be->SetPos({newX, newY, newZ});
m_BlockEntities->insert({newIdx, std::move(be)});
}
}
@ -1614,7 +1614,7 @@ void cBlockArea::MirrorYZNoMeta(void)
auto newY = be->GetPosY();
auto newZ = be->GetPosZ();
auto newIdx = MakeIndex(newX, newY, newZ);
be->SetPos(newX, newY, newZ);
be->SetPos({newX, newY, newZ});
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))
{
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))
{
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))
{
// 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);
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;
}
}
// No BE found in a_Src, insert a new empty one:
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
}
@ -2676,7 +2676,7 @@ void cBlockArea::RescanBlockEntities(void)
}
// Create a new BE for this block:
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
}
@ -2962,11 +2962,9 @@ void cBlockArea::cChunkReader::BlockEntity(cBlockEntity * a_BlockEntity)
{
return;
}
auto areaX = a_BlockEntity->GetPosX() - m_Area.m_Origin.x;
auto areaY = a_BlockEntity->GetPosY() - m_Area.m_Origin.y;
auto areaZ = a_BlockEntity->GetPosZ() - m_Area.m_Origin.z;
auto Idx = m_Area.MakeIndex(areaX, areaY, areaZ);
m_Area.m_BlockEntities->insert({Idx, a_BlockEntity->Clone(areaX, areaY, areaZ)});
auto areaPos = a_BlockEntity->GetPos() - m_Area.m_Origin;
auto Idx = m_Area.MakeIndex(areaPos);
m_Area.m_BlockEntities->insert({Idx, a_BlockEntity->Clone(areaPos)});
}

View File

@ -388,6 +388,15 @@ public:
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); }
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
{
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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, 1, 1, a_World),
cBeaconEntity::cBeaconEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, 1, 1, a_World),
m_IsActive(false),
m_BeaconLevel(0),
m_PrimaryEffect(cEntityEffect::effNoEffect),
@ -138,9 +138,9 @@ bool cBeaconEntity::SetSecondaryEffect(cEntityEffect::eType a_Effect)
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))
{
return true;
@ -195,7 +195,7 @@ void cBeaconEntity::UpdateBeacon(void)
GetWindow()->SetProperty(0, m_BeaconLevel);
}
Vector3d BeaconPosition(m_PosX, m_PosY, m_PosZ);
Vector3d BeaconPosition(m_Pos);
GetWorld()->ForEachPlayer([=](cPlayer & a_Player)
{
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);
Vector3d BeaconPosition(m_PosX, m_PosY, m_PosZ);
Vector3d BeaconPosition(m_Pos);
GetWorld()->ForEachPlayer([=](cPlayer & a_Player)
{
auto PlayerPosition = a_Player.GetPosition();
@ -263,7 +263,7 @@ void cBeaconEntity::GiveEffects(void)
void cBeaconEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cBeaconEntity &>(a_Src);
m_BeaconLevel = src.m_BeaconLevel;
m_Contents.CopyFrom(src.m_Contents);
@ -305,7 +305,7 @@ bool cBeaconEntity::UsedBy(cPlayer * a_Player)
cWindow * Window = GetWindow();
if (Window == nullptr)
{
OpenWindow(new cBeaconWindow(m_PosX, m_PosY, m_PosZ, this));
OpenWindow(new cBeaconWindow(this));
Window = GetWindow();
}

View File

@ -19,14 +19,16 @@
class cBeaconEntity :
public cBlockEntityWithItems
{
typedef cBlockEntityWithItems Super;
public:
// tolua_end
using super = cBlockEntityWithItems;
public: // tolua_export
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:
virtual void CopyFrom(const cBlockEntity & a_Src) override;

View File

@ -9,8 +9,12 @@
#include "../ClientHandle.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)
{
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)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cBedEntity &>(a_Src);
m_Color = src.m_Color;
}

View File

@ -14,13 +14,14 @@
class cBedEntity :
public cBlockEntity
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
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

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)
m_PosX = a_NewBlockX;
m_PosY = a_NewBlockY;
m_PosZ = a_NewBlockZ;
m_Pos = a_NewPos;
}
@ -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)
{
case E_BLOCK_BEACON: return new cBeaconEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_BED: return new cBedEntity (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_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_CHEST: return new cChestEntity (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_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_DROPPER: return new cDropperEntity (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_BlockX, a_BlockY, a_BlockZ, 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_FURNACE: return new cFurnaceEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World);
case E_BLOCK_JUKEBOX: return new cJukeboxEntity (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_BlockX, a_BlockY, a_BlockZ, 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_NOTE_BLOCK: return new cNoteEntity (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_BlockX, a_BlockY, a_BlockZ, 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_WALLSIGN: return new cSignEntity (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_Pos, 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_Pos, 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_Pos, 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_Pos, 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_Pos, 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_Pos, 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_Pos, 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_Pos, 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_Pos, a_World);
case E_BLOCK_WALLSIGN: return new cSignEntity (a_BlockType, a_BlockMeta, a_Pos, a_World);
default:
{
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);
return res.release();
}

View File

@ -9,19 +9,19 @@
#define BLOCKENTITY_PROTODEF(classname) \
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; \
} \
static const char * GetClassStatic(void) \
static const char * GetClassStatic() \
{ \
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
{
protected:
cBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
m_PosX(a_BlockX),
m_PosY(a_BlockY),
m_PosZ(a_BlockZ),
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)),
cBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World) :
m_Pos(a_Pos),
m_RelX(a_Pos.x - cChunkDef::Width * FAST_FLOOR_DIV(a_Pos.x, cChunkDef::Width)),
m_RelZ(a_Pos.z - cChunkDef::Width * FAST_FLOOR_DIV(a_Pos.z, cChunkDef::Width)),
m_BlockType(a_BlockType),
m_BlockMeta(a_BlockMeta),
m_World(a_World)
@ -57,7 +55,7 @@ public:
virtual ~cBlockEntity() {} // force a virtual destructor in all descendants
virtual void Destroy(void) {}
virtual void Destroy() {}
void SetWorld(cWorld * a_World)
{
@ -66,27 +64,27 @@ public:
/** 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.
Asserts when the block entity is assigned to a world. */
void SetPos(int a_NewBlockX, int a_NewBlockY, int a_NewBlockZ);
Asserts that the block entity is not assigned to a world. */
void SetPos(Vector3i a_NewPos);
/** Returns true if the specified blocktype is supposed to have an associated block entity. */
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
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.
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.
Each non-abstract descendant should override to copy its specific properties, and call
Super::CopyFrom(a_Src) to copy the common ones. */
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";
}
@ -94,29 +92,31 @@ public:
/** 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); }
/** Returns the name of the tompost class (the most descendant). Used for Lua bindings to push the correct object type. */
virtual const char * GetClass(void) const { return GetClassStatic(); }
/** Returns the name of the topmost class (the most descendant). Used for Lua bindings to push the correct object type. */
virtual const char * GetClass() const { return GetClassStatic(); }
/** 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
// Position, in absolute block coordinates:
Vector3i GetPos(void) const { return Vector3i{m_PosX, m_PosY, m_PosZ}; }
int GetPosX(void) const { return m_PosX; }
int GetPosY(void) const { return m_PosY; }
int GetPosZ(void) const { return m_PosZ; }
Vector3i GetPos() const { return m_Pos; }
int GetPosX() const { return m_Pos.x; }
int GetPosY() const { return m_Pos.y; }
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); }
int GetChunkZ(void) const { return FAST_FLOOR_DIV(m_PosZ, cChunkDef::Width); }
cWorld * GetWorld() const { return m_World; }
int GetRelX(void) const { return m_RelX; }
int GetRelZ(void) const { return m_RelZ; }
int GetChunkX() const { return FAST_FLOOR_DIV(m_Pos.x, cChunkDef::Width); }
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
@ -135,9 +135,11 @@ public:
return false;
}
protected:
/** 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 */
int m_RelX, m_RelZ;

View File

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

View File

@ -26,18 +26,19 @@ class cBlockEntityWithItems :
// tolua_begin
public cBlockEntityWindowOwner
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cBlockEntityWithItems)
cBlockEntityWithItems(
BLOCKTYPE a_BlockType, // Type 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
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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
cBrewingstandEntity::cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_IsDestroyed(false),
m_IsBrewing(false),
m_TimeBrewed(0),
@ -42,7 +42,7 @@ cBrewingstandEntity::~cBrewingstandEntity()
void cBrewingstandEntity::Destroy()
{
m_IsDestroyed = true;
Super::Destroy();
super::Destroy();
}
@ -51,7 +51,7 @@ void cBrewingstandEntity::Destroy()
void cBrewingstandEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cBrewingstandEntity &>(a_Src);
m_IsBrewing = src.m_IsBrewing;
for (size_t i = 0; i < ARRAYCOUNT(m_CurrentBrewingRecipes); ++i)
@ -158,7 +158,7 @@ bool cBrewingstandEntity::UsedBy(cPlayer * a_Player)
cWindow * Window = GetWindow();
if (Window == nullptr)
{
OpenWindow(new cBrewingstandWindow(m_PosX, m_PosY, m_PosZ, this));
OpenWindow(new cBrewingstandWindow(this));
Window = GetWindow();
}
@ -201,7 +201,7 @@ void cBrewingstandEntity::BroadcastProgress(short a_ProgressbarID, short a_Value
void cBrewingstandEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{
Super::OnSlotChanged(a_ItemGrid, a_SlotNum);
super::OnSlotChanged(a_ItemGrid, a_SlotNum);
if (m_IsDestroyed)
{

View File

@ -18,9 +18,14 @@ class cClientHandle;
class cBrewingstandEntity :
public cBlockEntityWithItems
{
typedef cBlockEntityWithItems Super;
// tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public:
enum
{
bsLeftBottle = 0, // Left bottle slot number
@ -38,7 +43,7 @@ public:
BLOCKENTITY_PROTODEF(cBrewingstandEntity)
/** 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;

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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
cChestEntity::cChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_NumActivePlayers(0),
m_Neighbour(nullptr)
{
int ChunkX = 0, ChunkZ = 0;
cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ);
auto chunkCoord = cChunkDef::BlockToChunk(a_Pos);
if (
(m_World != nullptr) &&
m_World->IsChunkValid(ChunkX, ChunkZ)
m_World->IsChunkValid(chunkCoord.m_ChunkX, chunkCoord.m_ChunkZ)
)
{
ScanNeighbours();
@ -50,7 +49,7 @@ cChestEntity::~cChestEntity()
void cChestEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cChestEntity &>(a_Src);
m_Contents.CopyFrom(src.m_Contents);
@ -66,7 +65,7 @@ void cChestEntity::CopyFrom(const cBlockEntity & a_Src)
void cChestEntity::SendTo(cClientHandle & a_Client)
{
// 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
// 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
int ChunkX, ChunkZ;
cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ);
m_World->MarkChunkDirty(ChunkX, ChunkZ);
auto chunkCoords = cChunkDef::BlockToChunk(m_Pos);
m_World->MarkChunkDirty(chunkCoords.m_ChunkX, chunkCoords.m_ChunkZ);
return true;
}
@ -152,10 +150,10 @@ void cChestEntity::ScanNeighbours()
// Scan horizontally adjacent blocks for any neighbouring chest of the same type:
if (
m_World->DoWithChestAt(m_PosX - 1, m_PosY, m_PosZ, FindNeighbour) ||
m_World->DoWithChestAt(m_PosX + 1, m_PosY, m_PosZ, FindNeighbour) ||
m_World->DoWithChestAt(m_PosX, m_PosY, m_PosZ - 1, FindNeighbour) ||
m_World->DoWithChestAt(m_PosX, m_PosY, m_PosZ + 1, FindNeighbour)
m_World->DoWithChestAt(m_Pos.x - 1, m_Pos.y, m_Pos.z, FindNeighbour) ||
m_World->DoWithChestAt(m_Pos.x + 1, m_Pos.y, m_Pos.z, FindNeighbour) ||
m_World->DoWithChestAt(m_Pos.x, m_Pos.y, m_Pos.z - 1, FindNeighbour) ||
m_World->DoWithChestAt(m_Pos.x, m_Pos.y, m_Pos.z + 1, FindNeighbour)
)
{
m_Neighbour->m_Neighbour = this;

View File

@ -18,9 +18,14 @@ class cClientHandle;
class cChestEntity :
public cBlockEntityWithItems
{
typedef cBlockEntityWithItems Super;
// tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public:
enum
{
ContentsHeight = 3,
@ -32,7 +37,7 @@ public:
BLOCKENTITY_PROTODEF(cChestEntity)
/** 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;
@ -59,6 +64,7 @@ public:
/** Sets the number of players who currently have this chest open */
void SetNumberOfPlayers(int a_NumActivePlayers) { m_NumActivePlayers = a_NumActivePlayers; }
private:
/** Number of players who currently have this chest open */
@ -90,10 +96,9 @@ private:
}
m_World->MarkChunkDirty(GetChunkX(), GetChunkZ());
auto Pos = Vector3i(m_PosX, m_PosY, m_PosZ);
m_World->DoWithChunkAt(Pos, [&](cChunk & a_Chunk)
m_World->DoWithChunkAt(m_Pos, [&](cChunk & a_Chunk)
{
m_World->GetRedstoneSimulator()->WakeUp(Pos, &a_Chunk);
m_World->GetRedstoneSimulator()->WakeUp(m_Pos, &a_Chunk);
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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
cCommandBlockEntity::cCommandBlockEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_ShouldExecute(false),
m_Result(0)
{
@ -115,7 +115,7 @@ void cCommandBlockEntity::Activate(void)
void cCommandBlockEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cCommandBlockEntity &>(a_Src);
m_Command = src.m_Command;
m_LastOutput = src.m_LastOutput;

View File

@ -20,16 +20,16 @@
class cCommandBlockEntity :
public cBlockEntity
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cCommandBlockEntity)
/** 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:
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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World)
cDispenserEntity::cDispenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{
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)
{
int DispX = m_RelX;
int DispY = m_PosY;
int DispZ = m_RelZ;
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
AddDropSpenserDir(DispX, DispY, DispZ, Meta);
cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(DispX, DispZ);
if (DispChunk == nullptr)
Vector3i dispRelCoord(GetRelPos());
auto meta = a_Chunk.GetMeta(dispRelCoord);
AddDropSpenserDir(dispRelCoord, meta);
auto dispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(dispRelCoord.x, dispRelCoord.z);
if (dispChunk == nullptr)
{
// Would dispense into / interact with a non-loaded chunk, ignore the tick
return;
}
BLOCKTYPE DispBlock = DispChunk->GetBlock(DispX, DispY, DispZ);
int BlockX = (DispX + DispChunk->GetPosX() * cChunkDef::Width);
int BlockZ = (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
BLOCKTYPE dispBlock = dispChunk->GetBlock(dispRelCoord);
auto dispAbsCoord = dispChunk->RelativeToAbsolute(dispRelCoord);
// Dispense the item:
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);
}
@ -55,15 +52,15 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
{
case E_ITEM_BUCKET:
{
LOGD("Dispensing empty bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock);
switch (DispBlock)
LOGD("Dispensing empty bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock);
switch (dispBlock)
{
case E_BLOCK_STATIONARY_WATER:
case E_BLOCK_WATER:
{
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;
}
@ -72,7 +69,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
{
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;
}
@ -87,10 +84,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_WATER_BUCKET:
{
LOGD("Dispensing water bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock);
if (EmptyLiquidBucket(DispBlock, a_SlotNum))
LOGD("Dispensing water bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock);
if (EmptyLiquidBucket(dispBlock, a_SlotNum))
{
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_WATER, 0);
dispChunk->SetBlock(dispRelCoord, E_BLOCK_WATER, 0);
}
else
{
@ -101,10 +98,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_LAVA_BUCKET:
{
LOGD("Dispensing lava bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock);
if (EmptyLiquidBucket(DispBlock, a_SlotNum))
LOGD("Dispensing lava bucket in slot %d; dispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(dispBlock).c_str(), dispBlock);
if (EmptyLiquidBucket(dispBlock, a_SlotNum))
{
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_LAVA, 0);
dispChunk->SetBlock(dispRelCoord, E_BLOCK_LAVA, 0);
}
else
{
@ -115,9 +112,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_SPAWN_EGG:
{
double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width);
double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
if (m_World->SpawnMob(MobX, DispY, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage), false) != cEntity::INVALID_ID)
double MobX = 0.5 + dispAbsCoord.x;
double MobZ = 0.5 + dispAbsCoord.z;
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);
}
@ -127,11 +124,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_BLOCK_TNT:
{
// 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);
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_World->SpawnPrimedTNT(Vector3d(0.5, 0.5, 0.5) + dispAbsCoord, 80, 0); // 80 ticks fuse, no initial velocity
m_Contents.ChangeSlotCount(a_SlotNum, -1);
}
break;
@ -140,9 +135,9 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_FLINT_AND_STEEL:
{
// 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);
@ -156,7 +151,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
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);
}
@ -165,7 +160,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
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);
}
@ -174,7 +169,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
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);
}
@ -183,7 +178,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
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);
}
@ -192,7 +187,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
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);
}
@ -201,7 +196,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
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);
}
@ -215,7 +210,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
DropFromSlot(a_Chunk, a_SlotNum);
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);
}
@ -229,16 +224,16 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
case E_ITEM_ACACIA_BOAT:
case E_ITEM_DARK_OAK_BOAT:
{
Vector3d SpawnPos;
if (IsBlockWater(DispBlock))
Vector3d spawnPos = dispAbsCoord;
if (IsBlockWater(dispBlock))
{
// 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
SpawnPos.Set(BlockX, DispY, BlockZ);
// No adjustment needed
}
else
{
@ -247,10 +242,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
break;
}
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 += 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);
if (m_World->SpawnBoat(SpawnPos, cBoat::ItemToMaterial(SlotItem)))
if (m_World->SpawnBoat(spawnPos, cBoat::ItemToMaterial(SlotItem)))
{
m_Contents.ChangeSlotCount(a_SlotNum, -1);
}
@ -259,7 +254,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
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);
}
@ -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(
static_cast<double>(a_BlockX + 0.5),
static_cast<double>(a_BlockY + 0.5),
static_cast<double>(a_BlockZ + 0.5),
return m_World->CreateProjectile(Vector3d(0.5, 0.5, 0.5) + a_BlockPos,
a_Kind, nullptr, a_Item, &a_ShootVector
);
}

View File

@ -11,22 +11,42 @@
class cDispenserEntity :
public cDropSpenserEntity
{
typedef cDropSpenserEntity Super;
public:
// tolua_end
using super = cDropSpenserEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cDispenserEntity)
/** 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
/** 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);
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. */
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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
cDropSpenserEntity::cDropSpenserEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
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)
{
case E_META_DROPSPENSER_FACING_YM: a_BlockY--; return;
case E_META_DROPSPENSER_FACING_YP: a_BlockY++; return;
case E_META_DROPSPENSER_FACING_ZM: a_BlockZ--; return;
case E_META_DROPSPENSER_FACING_ZP: a_BlockZ++; return;
case E_META_DROPSPENSER_FACING_XM: a_BlockX--; return;
case E_META_DROPSPENSER_FACING_XP: a_BlockX++; return;
case E_META_DROPSPENSER_FACING_YM: a_RelCoord.y--; return;
case E_META_DROPSPENSER_FACING_YP: a_RelCoord.y++; return;
case E_META_DROPSPENSER_FACING_ZM: a_RelCoord.z--; return;
case E_META_DROPSPENSER_FACING_ZP: a_RelCoord.z++; return;
case E_META_DROPSPENSER_FACING_XM: a_RelCoord.x--; return;
case E_META_DROPSPENSER_FACING_XP: a_RelCoord.x++; return;
}
LOGWARNING("%s: Unhandled direction: %d", __FUNCTION__, a_Direction);
return;
@ -75,7 +75,7 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk)
if (SlotsCnt == 0)
{
// 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;
}
@ -85,7 +85,7 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk)
DropSpenseFromSlot(a_Chunk, OccupiedSlots[RandomSlot]);
// 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;
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;
}
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)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cDropSpenserEntity &>(a_Src);
m_Contents.CopyFrom(src.m_Contents);
m_ShouldDropSpense = src.m_ShouldDropSpense;
@ -157,7 +157,7 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player)
cWindow * Window = GetWindow();
if (Window == nullptr)
{
OpenWindow(new cDropSpenserWindow(m_PosX, m_PosY, m_PosZ, this));
OpenWindow(new cDropSpenserWindow(this));
Window = GetWindow();
}
@ -177,11 +177,9 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player)
void cDropSpenserEntity::DropFromSlot(cChunk & a_Chunk, int a_SlotNum)
{
int DispX = m_PosX;
int DispY = m_PosY;
int DispZ = m_PosZ;
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
AddDropSpenserDir(DispX, DispY, DispZ, Meta);
Vector3i dispCoord(m_Pos);
auto Meta = a_Chunk.GetMeta(GetRelPos());
AddDropSpenserDir(dispCoord, Meta);
cItems Pickups;
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;
MicroX = DispX + 0.5;
MicroY = DispY + 0.4; // Slightly less than half, to accomodate actual texture hole on DropSpenser
MicroZ = DispZ + 0.5;
MicroX = dispCoord.x + 0.5;
MicroY = dispCoord.y + 0.4; // Slightly less than half, to accomodate actual texture hole on DropSpenser
MicroZ = dispCoord.z + 0.5;
m_World->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ, PickupSpeedX, PickupSpeedY, PickupSpeedZ);

View File

@ -26,9 +26,14 @@ class cClientHandle;
class cDropSpenserEntity :
public cBlockEntityWithItems
{
typedef cBlockEntityWithItems Super;
// tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public:
enum
{
ContentsHeight = 3,
@ -39,7 +44,7 @@ public:
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;
// cBlockEntity overrides:
@ -51,7 +56,7 @@ public:
// tolua_begin
/** 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 */
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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World)
cDropperEntity::cDropperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{
ASSERT(a_BlockType == E_BLOCK_DROPPER);
}

View File

@ -19,25 +19,22 @@
class cDropperEntity :
public cDropSpenserEntity
{
typedef cDropSpenserEntity Super;
public:
// tolua_end
using super = cDropSpenserEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cDropperEntity)
/** 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:
// cDropSpenserEntity overrides:
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

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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
cEnderChestEntity::cEnderChestEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World),
cBlockEntityWindowOwner(this)
{
ASSERT(a_BlockType == E_BLOCK_ENDER_CHEST);
@ -40,7 +40,7 @@ cEnderChestEntity::~cEnderChestEntity()
void cEnderChestEntity::SendTo(cClientHandle & a_Client)
{
// 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 cBlockEntityWindowOwner
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
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;
// 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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World)
cFlowerPotEntity::cFlowerPotEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{
ASSERT(a_BlockType == E_BLOCK_FLOWER_POT);
}
@ -31,7 +31,7 @@ void cFlowerPotEntity::Destroy(void)
ASSERT(m_World != nullptr);
cItems Pickups;
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();
}
@ -43,7 +43,7 @@ void cFlowerPotEntity::Destroy(void)
void cFlowerPotEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cFlowerPotEntity &>(a_Src);
m_Item = src.m_Item;
}

View File

@ -20,16 +20,16 @@
class cFlowerPotEntity :
public cBlockEntity
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cFlowerPotEntity)
/** 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

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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
cFurnaceEntity::cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_CurrentRecipe(nullptr),
m_IsDestroyed(false),
m_IsCooking(a_BlockType == E_BLOCK_LIT_FURNACE),
@ -58,7 +58,7 @@ cFurnaceEntity::~cFurnaceEntity()
void cFurnaceEntity::Destroy()
{
m_IsDestroyed = true;
Super::Destroy();
super::Destroy();
}
@ -67,7 +67,7 @@ void cFurnaceEntity::Destroy()
void cFurnaceEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cFurnaceEntity &>(a_Src);
m_Contents.CopyFrom(src.m_Contents);
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
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();
return false;
}
@ -142,7 +142,7 @@ bool cFurnaceEntity::UsedBy(cPlayer * a_Player)
cWindow * Window = GetWindow();
if (Window == nullptr)
{
OpenWindow(new cFurnaceWindow(m_PosX, m_PosY, m_PosZ, this));
OpenWindow(new cFurnaceWindow(this));
Window = GetWindow();
}
@ -255,7 +255,7 @@ void cFurnaceEntity::BurnNewFuel(void)
void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{
Super::OnSlotChanged(a_ItemGrid, a_SlotNum);
super::OnSlotChanged(a_ItemGrid, a_SlotNum);
if (m_IsDestroyed)
{
@ -433,6 +433,6 @@ void cFurnaceEntity::SetIsCooking(bool a_IsCooking)
if (m_IsCooking)
{
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 :
public cBlockEntityWithItems
{
typedef cBlockEntityWithItems Super;
// tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public:
enum
{
fsInput = 0, // Input slot number
@ -36,7 +41,7 @@ public:
BLOCKENTITY_PROTODEF(cFurnaceEntity)
/** 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;

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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
cHopperEntity::cHopperEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
m_LastMoveItemsInTick(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;
a_OutputY = m_PosY;
a_OutputZ = m_PosZ;
auto pos = GetPos();
switch (a_BlockMeta)
{
case E_META_HOPPER_FACING_XM: a_OutputX--; return true;
case E_META_HOPPER_FACING_XP: a_OutputX++; return true;
case E_META_HOPPER_FACING_YM: a_OutputY--; return true;
case E_META_HOPPER_FACING_ZM: a_OutputZ--; return true;
case E_META_HOPPER_FACING_ZP: a_OutputZ++; return true;
case E_META_HOPPER_FACING_XM: return {true, pos.addedX(-1)};
case E_META_HOPPER_FACING_XP: return {true, pos.addedX( 1)};
case E_META_HOPPER_FACING_YM: return {true, pos.addedY(-1)};
case E_META_HOPPER_FACING_ZM: return {true, pos.addedZ(-1)};
case E_META_HOPPER_FACING_ZP: return {true, pos.addedZ( 1)};
default:
{
// 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)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cHopperEntity &>(a_Src);
m_LastMoveItemsInTick = src.m_LastMoveItemsInTick;
m_LastMoveItemsOutTick = src.m_LastMoveItemsOutTick;
@ -127,7 +125,7 @@ bool cHopperEntity::UsedBy(cPlayer * a_Player)
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)
{
if (m_PosY >= cChunkDef::Height)
if (m_Pos.y >= cChunkDef::Height)
{
// This hopper is at the top of the world, no more blocks above
return false;
@ -150,7 +148,7 @@ bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
// Try moving an item in:
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_CHEST:
@ -170,7 +168,7 @@ bool cHopperEntity::MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick)
case E_BLOCK_DROPPER:
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;
}
}
@ -286,24 +284,23 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
}
// Get the coords of the block where to output items:
int OutX, OutY, OutZ;
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
if (!GetOutputBlockPos(Meta, OutX, OutY, OutZ))
auto meta = a_Chunk.GetMeta(GetRelPos());
auto out = GetOutputBlockPos(meta);
if (!out.first)
{
// Not attached to another container
return false;
}
if (OutY < 0)
if (out.second.y < 0)
{
// Cannot output below the zero-th block level
return false;
}
// Convert coords to relative:
int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width;
int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width;
cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ);
if (DestChunk == nullptr)
auto relCoord = a_Chunk.AbsoluteToRelative(out.second);
auto destChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(relCoord.x, relCoord.z);
if (destChunk == nullptr)
{
// The destination chunk has been unloaded, don't tick
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:
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_CHEST:
{
// Chests have special handling because of double-chests
res = MoveItemsToChest(*DestChunk, OutX, OutY, OutZ);
res = MoveItemsToChest(*destChunk, absCoord);
break;
}
case E_BLOCK_LIT_FURNACE:
case E_BLOCK_FURNACE:
{
// Furnaces have special handling because of the direction-to-slot relation
res = MoveItemsToFurnace(*DestChunk, OutX, OutY, OutZ, Meta);
res = MoveItemsToFurnace(*destChunk, absCoord, meta);
break;
}
case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER:
case E_BLOCK_HOPPER:
{
cBlockEntityWithItems * BlockEntity = static_cast<cBlockEntityWithItems *>(DestChunk->GetBlockEntity(OutX, OutY, OutZ));
if (BlockEntity == nullptr)
auto blockEntity = static_cast<cBlockEntityWithItems *>(destChunk->GetBlockEntity(absCoord));
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;
}
res = MoveItemsToGrid(*BlockEntity);
res = MoveItemsToGrid(*blockEntity);
break;
}
}
@ -357,55 +355,52 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{
cChestEntity * MainChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ));
if (MainChest == nullptr)
auto chestPos = GetPos().addedY(1);
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;
}
if (MoveItemsFromGrid(*MainChest))
if (MoveItemsFromGrid(*mainChest))
{
// Moved the item from the chest directly above the hopper
return true;
}
// 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;
}
Coords [] =
{
{1, 0},
{-1, 0},
{0, 1},
{0, -1},
{ 1, 1, 0},
{-1, 1, 0},
{ 0, 1, 1},
{ 0, 1, -1},
} ;
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
for (const auto & ofs: neighborOfs)
{
int x = m_RelX + Coords[i].x;
int z = m_RelZ + Coords[i].z;
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
if (Neighbor == nullptr)
auto neighborRelCoord = ofs.addedXZ(m_RelX, m_RelZ);
auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(neighborRelCoord.x, neighborRelCoord.z);
if (neighbor == nullptr)
{
continue;
}
BLOCKTYPE Block = Neighbor->GetBlock(x, m_PosY + 1, z);
if (Block != MainChest->GetBlockType())
BLOCKTYPE Block = neighbor->GetBlock(neighborRelCoord);
if (Block != mainChest->GetBlockType())
{
// Not the same kind of chest
continue;
}
cChestEntity * SideChest = static_cast<cChestEntity *>(Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z));
if (SideChest == nullptr)
auto neighborAbsCoord = neighbor->RelativeToAbsolute(neighborRelCoord);
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
{
if (MoveItemsFromGrid(*SideChest))
if (MoveItemsFromGrid(*sideChest))
{
return true;
}
@ -413,7 +408,7 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
return false;
}
// The chest was single and nothing could be moved
// The chest was empty
return false;
}
@ -423,27 +418,27 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
{
cFurnaceEntity * Furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ));
if (Furnace == nullptr)
auto furnace = static_cast<cFurnaceEntity *>(a_Chunk.GetBlockEntity(m_Pos.addedY(1)));
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;
}
// Try move from the output slot:
if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput))
if (MoveItemsFromSlot(*furnace, cFurnaceEntity::fsOutput))
{
cItem NewOutput(Furnace->GetOutputSlot());
Furnace->SetOutputSlot(NewOutput.AddCount(-1));
cItem NewOutput(furnace->GetOutputSlot());
furnace->SetOutputSlot(NewOutput.AddCount(-1));
return true;
}
// 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;
}
}
@ -458,7 +453,7 @@ bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
bool cHopperEntity::MoveItemsFromGrid(cBlockEntityWithItems & a_Entity)
{
cItemGrid & Grid = a_Entity.GetContents();
auto & Grid = a_Entity.GetContents();
int NumSlots = Grid.GetNumSlots();
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:
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)
{
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;
}
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:
static const struct
static const Vector3i neighborOfs [] =
{
int x, z;
}
Coords [] =
{
{1, 0},
{-1, 0},
{0, 1},
{0, -1},
{ 1, 0, 0},
{-1, 0, 0},
{ 0, 0, 1},
{ 0, 0, -1},
} ;
int RelX = a_BlockX - a_Chunk.GetPosX() * cChunkDef::Width;
int RelZ = a_BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width;
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
auto relCoord = a_Chunk.AbsoluteToRelative(a_Coords);
for (const auto & ofs: neighborOfs)
{
int x = RelX + Coords[i].x;
int z = RelZ + Coords[i].z;
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
if (Neighbor == nullptr)
auto otherHalfRelCoord = relCoord + ofs;
auto neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(otherHalfRelCoord.x, otherHalfRelCoord.z);
if (neighbor == nullptr)
{
continue;
}
BLOCKTYPE Block = Neighbor->GetBlock(x, a_BlockY, z);
auto Block = neighbor->GetBlock(otherHalfRelCoord);
if (Block != ConnectedChest->GetBlockType())
{
// Not the same kind of chest
continue;
}
cChestEntity * Chest = static_cast<cChestEntity *>(Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z));
if (Chest == nullptr)
auto chest = static_cast<cChestEntity *>(neighbor->GetBlockEntity(a_Coords + ofs));
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;
}
if (MoveItemsToGrid(*Chest))
if (MoveItemsToGrid(*chest))
{
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)
{
// Feed the input slot of the furnace
return MoveItemsToSlot(*Furnace, cFurnaceEntity::fsInput);
return MoveItemsToSlot(*furnace, cFurnaceEntity::fsInput);
}
else
{
// 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 :
public cBlockEntityWithItems
{
typedef cBlockEntityWithItems Super;
// tolua_end
using super = cBlockEntityWithItems;
// tolua_begin
public:
enum
@ -34,12 +38,12 @@ public:
BLOCKENTITY_PROTODEF(cHopperEntity)
/** 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 false if unattached.
Returns <false, undefined> if unattached.
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:
@ -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. */
bool MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SrcSlotNum);
/** Moves items to the chest at the specified coords. Returns true if contents have changed */
bool MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ);
/** Moves items to the chest at the specified absolute coords. Returns true if contents have changed */
bool MoveItemsToChest(cChunk & a_Chunk, Vector3i a_Coords);
/** Moves items to the furnace at the specified coords. Returns true if contents have changed */
bool MoveItemsToFurnace(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_HopperMeta);
/** Moves items to the furnace at the specified absolute coords. Returns true if contents have changed */
bool MoveItemsToFurnace(cChunk & a_Chunk, Vector3i a_Coords, NIBBLETYPE a_HopperMeta);
/** Moves items to the specified ItemGrid. Returns true if contents have changed */
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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
cJukeboxEntity::cJukeboxEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Record(0)
{
ASSERT(a_BlockType == E_BLOCK_JUKEBOX);
@ -31,7 +31,7 @@ cJukeboxEntity::~cJukeboxEntity()
void cJukeboxEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cJukeboxEntity &>(a_Src);
m_Record = src.m_Record;
}
@ -77,7 +77,7 @@ bool cJukeboxEntity::PlayRecord(int a_Record)
}
m_Record = a_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;
}
@ -96,9 +96,9 @@ bool cJukeboxEntity::EjectRecord(void)
cItems Drops;
Drops.push_back(cItem(static_cast<short>(m_Record), 1, 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->SetBlockMeta(m_PosX, m_PosY, m_PosZ, E_META_JUKEBOX_OFF);
m_World->SetBlockMeta(m_Pos, E_META_JUKEBOX_OFF);
return true;
}

View File

@ -12,15 +12,15 @@
class cJukeboxEntity :
public cBlockEntity
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
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;
// 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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
cMobHeadEntity::cMobHeadEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Type(SKULL_TYPE_SKELETON),
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)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cMobHeadEntity &>(a_Src);
m_OwnerName = src.m_OwnerName;
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)
{
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);
}

View File

@ -21,16 +21,16 @@
class cMobHeadEntity :
public cBlockEntity
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cMobHeadEntity)
/** 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

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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
cMobSpawnerEntity::cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Entity(mtPig),
m_SpawnDelay(100),
m_IsActive(false)
@ -28,7 +28,7 @@ cMobSpawnerEntity::cMobSpawnerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMe
void cMobSpawnerEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cMobSpawnerEntity &>(a_Src);
m_Entity = src.m_Entity;
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 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);
cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelX, RelZ);
@ -203,7 +203,7 @@ void cMobSpawnerEntity::SpawnEntity(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;
class cCallback : public cChunkDataCallback
@ -246,7 +246,7 @@ int cMobSpawnerEntity::GetNearbyPlayersNum(void)
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;
class cCallback : public cChunkDataCallback

View File

@ -16,16 +16,16 @@
// tolua_begin
class cMobSpawnerEntity :
public cBlockEntity
{
typedef cBlockEntity Super;
public:
// 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:
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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World),
cNoteEntity::cNoteEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_Pitch(0)
{
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)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cNoteEntity &>(a_Src);
m_Pitch = src.m_Pitch;
}
@ -48,7 +48,7 @@ void cNoteEntity::MakeSound(void)
char instrument;
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_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
float calcPitch = static_cast<float>(pow(2.0f, static_cast<float>(m_Pitch - 12.0f) / 12.0f));
m_World->BroadcastSoundEffect(
sampleName,
Vector3d(m_PosX, m_PosY, m_PosZ),
m_Pos,
3.0f,
calcPitch
);

View File

@ -30,15 +30,16 @@ enum ENUM_NOTE_INSTRUMENTS
class cNoteEntity :
public cBlockEntity
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
BLOCKENTITY_PROTODEF(cNoteEntity)
/** 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 {}
// 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):
Super(a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_World)
cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{
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)
{
Super::CopyFrom(a_Src);
super::CopyFrom(a_Src);
auto & src = static_cast<const cSignEntity &>(a_Src);
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)
{
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 :
public cBlockEntity
{
typedef cBlockEntity Super;
public:
// tolua_end
using super = cBlockEntity;
public: // tolua_export
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 */
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

View File

@ -89,7 +89,7 @@ public:
// New knot? needs to init and produce sound effect
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();
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);
}
auto clone = be->Clone(posX, posY, posZ);
auto clone = be->Clone({posX, posY, posZ});
clone->SetWorld(m_World);
AddBlockEntityClean(clone);
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
);
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());
cBlockHandler::NeighborChanged(ChunkInterface, Absolute.x, Absolute.y - 1, Absolute.z, BLOCK_FACE_YP);
break;
@ -1435,12 +1435,12 @@ void cChunk::CreateBlockEntities(void)
{
auto RelPos = IndexToCoordinate(BlockIdx);
RelPos.y += static_cast<int>(SectionIdx * cChunkData::SectionHeight);
auto WorldPos = RelativeToAbsolute(RelPos, m_PosX, m_PosZ);
auto WorldPos = RelativeToAbsolute(RelPos);
if (!HasBlockEntityAt(WorldPos))
{
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);
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
@ -1576,7 +1576,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
case E_BLOCK_BREWING_STAND:
{
// 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;
}
} // switch (a_BlockType)

View File

@ -479,6 +479,14 @@ public:
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:
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)
{
#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)
{
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)
{
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) :
super(pkArrow, a_Creator, a_X, a_Y, a_Z, 0.5, 0.5),
cArrowEntity::cArrowEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkArrow, a_Creator, a_Pos, 0.5, 0.5),
m_PickupState(psNoPickup),
m_DamageCoeff(2),
m_IsCritical(false),

View File

@ -20,9 +20,15 @@
class cArrowEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
// tolua_end
using super = cProjectileEntity;
// tolua_begin
public:
/** Determines when the arrow can be picked up (depending on player gamemode). Corresponds to the MCA file "pickup" field */
enum ePickupState
{
@ -36,7 +42,7 @@ public:
CLASS_PROTODEF(cArrowEntity)
/** 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 */
cArrowEntity(cPlayer & a_Player, double a_Force);

View File

@ -14,7 +14,7 @@
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_DamageTaken(0.0f), m_Material(a_Material),
m_RightPaddleUsed(false), m_LeftPaddleUsed(false)

View File

@ -35,6 +35,8 @@ public:
CLASS_PROTODEF(cBoat)
cBoat(Vector3d a_Pos, eMaterial a_Material);
// cEntity overrides:
virtual void SpawnOn(cClientHandle & a_ClientHandle) 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 HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override;
cBoat(Vector3d a_Pos, eMaterial a_Material);
int GetLastDamage(void) const { return m_LastDamage; }
int GetForwardDirection(void) const { return m_ForwardDirection; }

View File

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

View File

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

View File

@ -32,7 +32,7 @@ static UInt32 GetNextUniqueID(void)
////////////////////////////////////////////////////////////////////////////////
// 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_Health(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_Gravity(-9.81f),
m_AirDrag(0.02f),
m_LastPosition(a_X, a_Y, a_Z),
m_LastPosition(a_Pos),
m_EntityType(a_EntityType),
m_World(nullptr),
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_HeadYaw(0.0),
m_Rot(0.0, 0.0, 0.0),
m_Position(a_X, a_Y, a_Z),
m_LastSentPosition(a_X, a_Y, a_Z),
m_Position(a_Pos),
m_LastSentPosition(a_Pos),
m_WaterSpeed(0, 0, 0),
m_Mass (0.001), // Default 1g
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.
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();
/** Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed).
@ -558,7 +558,9 @@ public:
@return exposure rate */
virtual float GetExplosionExposureRate(Vector3d a_ExplosionPosition, float a_ExlosionPower);
protected:
/** Structure storing the portal delay timer and cooldown boolean */
struct sPortalCooldownData
{
@ -570,6 +572,7 @@ protected:
bool m_ShouldPreventTeleportation;
};
/** Measured in meters / second (m / s) */
Vector3d m_Speed;
@ -686,6 +689,7 @@ protected:
Only to be used when the caller will broadcast a teleport or equivalent to clients. */
virtual void ResetPosition(Vector3d a_NewPos);
private:
/** 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) :
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);
}

View File

@ -20,15 +20,13 @@
class cExpBottleEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
public:
// 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);

View File

@ -5,25 +5,10 @@
#include "../ClientHandle.h"
cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward)
: cEntity(etExpOrb, a_X, a_Y, a_Z, 0.98, 0.98)
, m_Reward(a_Reward)
, 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)
cExpOrb::cExpOrb(Vector3d a_Pos, int a_Reward):
super(etExpOrb, a_Pos, 0.98, 0.98), // TODO: Check size
m_Reward(a_Reward),
m_Timer(0)
{
SetMaxHealth(5);
SetHealth(5);

View File

@ -18,8 +18,7 @@ public:
CLASS_PROTODEF(cExpOrb)
cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward);
cExpOrb(const Vector3d & a_Pos, int a_Reward);
cExpOrb(Vector3d a_Pos, int a_Reward);
// Override functions
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) :
super(etFallingBlock, a_BlockPosition.x + 0.5f, a_BlockPosition.y, a_BlockPosition.z + 0.5f, 0.98, 0.98),
cFallingBlock::cFallingBlock(Vector3i a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) :
super(etFallingBlock, Vector3d(0.5, 0, 0.5) + a_BlockPosition, 0.98, 0.98),
m_BlockType(a_BlockType),
m_BlockMeta(a_BlockMeta),
m_OriginalPosition(a_BlockPosition)

View File

@ -8,19 +8,20 @@
// tolua_begin
class cFallingBlock :
public cEntity
{
typedef cEntity super;
public:
// tolua_end
using super = cEntity;
public: // tolua_export
CLASS_PROTODEF(cFallingBlock)
/** Creates a new falling block. a_BlockPosition is expected in world coords */
cFallingBlock(const Vector3i & a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
/** Creates a new falling block.
a_BlockPosition is expected in world coords */
cFallingBlock(Vector3i a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
// 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) :
super(pkFireCharge, a_Creator, a_X, a_Y, a_Z, 0.3125, 0.3125)
cFireChargeEntity::cFireChargeEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkFireCharge, a_Creator, a_Pos, 0.3125, 0.3125)
{
SetSpeed(a_Speed);
SetGravity(0);

View File

@ -20,15 +20,15 @@
class cFireChargeEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
public:
// tolua_end
using super = cProjectileEntity;
public: // tolua_export
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:

View File

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

View File

@ -20,15 +20,15 @@
class cFireworkEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
public:
// tolua_end
using super = cProjectileEntity;
public: // tolua_export
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

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) :
cEntity(etFloater, a_X, a_Y, a_Z, 0.2, 0.2),
m_BitePos(Vector3d(a_X, a_Y, a_Z)),
cFloater::cFloater(Vector3d a_Pos, Vector3d a_Speed, UInt32 a_PlayerID, int a_CountDownTime) :
super(etFloater, a_Pos, 0.2, 0.2),
m_BitePos(a_Pos),
m_CanPickupItem(false),
m_PickupCountDown(0),
m_CountDownTime(a_CountDownTime),

View File

@ -11,14 +11,15 @@
class cFloater :
public cEntity
{
typedef cEntity super;
public:
// tolua_end
using super = cEntity;
public: // tolua_export
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 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) :
super(pkGhastFireball, a_Creator, a_X, a_Y, a_Z, 1, 1)
cGhastFireballEntity::cGhastFireballEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkGhastFireball, a_Creator, a_Pos, 1, 1)
{
SetSpeed(a_Speed);
SetGravity(0);

View File

@ -20,15 +20,15 @@
class cGhastFireballEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
public:
// tolua_end
using super = cProjectileEntity;
public: // tolua_export
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:

View File

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

View File

@ -11,15 +11,15 @@
class cHangingEntity :
public cEntity
{
typedef cEntity super;
public:
// tolua_end
using super = cEntity;
public: // tolua_export
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

View File

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

View File

@ -11,15 +11,15 @@
class cItemFrame :
public cHangingEntity
{
typedef cHangingEntity super;
public:
// tolua_end
using super = cHangingEntity;
public: // tolua_export
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

View File

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

View File

@ -13,15 +13,14 @@ class cWorldInterface;
class cLeashKnot :
public cHangingEntity
{
typedef cHangingEntity super;
public:
// tolua_end
using super = cHangingEntity;
public: // tolua_export
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 */
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_LastDamage(0),
m_DetectorRailPosition(0, 0, 0),
@ -1164,8 +1167,8 @@ void cMinecart::Destroyed()
////////////////////////////////////////////////////////////////////////////////
// cRideableMinecart:
cRideableMinecart::cRideableMinecart(double a_X, double a_Y, double a_Z, const cItem & a_Content, int a_Height) :
super(mpNone, a_X, a_Y, a_Z),
cRideableMinecart::cRideableMinecart(Vector3d a_Pos, const cItem & a_Content, int a_Height):
super(mpNone, a_Pos),
m_Content(a_Content),
m_Height(a_Height)
{
@ -1209,8 +1212,8 @@ void cRideableMinecart::OnRightClicked(cPlayer & a_Player)
////////////////////////////////////////////////////////////////////////////////
// cMinecartWithChest:
cMinecartWithChest::cMinecartWithChest(double a_X, double a_Y, double a_Z) :
super(mpChest, a_X, a_Y, a_Z),
cMinecartWithChest::cMinecartWithChest(Vector3d a_Pos):
super(mpChest, a_Pos),
cEntityWindowOwner(this),
m_Contents(ContentsWidth, ContentsHeight)
{
@ -1283,8 +1286,8 @@ void cMinecartWithChest::Destroyed()
////////////////////////////////////////////////////////////////////////////////
// cMinecartWithFurnace:
cMinecartWithFurnace::cMinecartWithFurnace(double a_X, double a_Y, double a_Z) :
super(mpFurnace, a_X, a_Y, a_Z),
cMinecartWithFurnace::cMinecartWithFurnace(Vector3d a_Pos):
super(mpFurnace, a_Pos),
m_FueledTimeLeft(-1),
m_IsFueled(false)
{
@ -1350,8 +1353,8 @@ void cMinecartWithFurnace::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk
////////////////////////////////////////////////////////////////////////////////
// cMinecartWithTNT:
cMinecartWithTNT::cMinecartWithTNT(double a_X, double a_Y, double a_Z) :
super(mpTNT, a_X, a_Y, a_Z)
cMinecartWithTNT::cMinecartWithTNT(Vector3d a_Pos):
super(mpTNT, a_Pos)
{
}
@ -1364,8 +1367,8 @@ cMinecartWithTNT::cMinecartWithTNT(double a_X, double a_Y, double a_Z) :
////////////////////////////////////////////////////////////////////////////////
// cMinecartWithHopper:
cMinecartWithHopper::cMinecartWithHopper(double a_X, double a_Y, double a_Z) :
super(mpHopper, a_X, a_Y, a_Z)
cMinecartWithHopper::cMinecartWithHopper(Vector3d a_Pos):
super(mpHopper, a_Pos)
{
}

View File

@ -20,7 +20,7 @@
class cMinecart :
public cEntity
{
typedef cEntity super;
using super = cEntity;
public:
CLASS_PROTODEF(cMinecart)
@ -45,7 +45,9 @@ public:
int LastDamage(void) const { return m_LastDamage; }
ePayload GetPayload(void) const { return m_Payload; }
protected:
ePayload m_Payload;
int m_LastDamage;
Vector3i m_DetectorRailPosition;
@ -57,7 +59,7 @@ protected:
// Overwrite to enforce speed limit
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
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 :
public cMinecart
{
typedef cMinecart super;
using super = cMinecart;
public:
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;}
int GetBlockHeight(void) const {return m_Height;}
// cEntity overrides:
virtual void OnRightClicked(cPlayer & a_Player) override;
protected:
cItem m_Content;
int m_Height;
} ;
@ -121,12 +127,13 @@ class cMinecartWithChest :
public cItemGrid::cListener,
public cEntityWindowOwner
{
typedef cMinecart super;
using super = cMinecart;
public:
CLASS_PROTODEF(cMinecartWithChest)
cMinecartWithChest(double a_X, double a_Y, double a_Z);
cMinecartWithChest(Vector3d a_Pos);
enum
{
@ -137,7 +144,9 @@ public:
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); }
protected:
cItemGrid m_Contents;
void OpenNewWindow(void);
virtual void Destroyed() override;
@ -169,12 +178,13 @@ protected:
class cMinecartWithFurnace :
public cMinecart
{
typedef cMinecart super;
using super = cMinecart;
public:
CLASS_PROTODEF(cMinecartWithFurnace)
cMinecartWithFurnace(double a_X, double a_Y, double a_Z);
cMinecartWithFurnace(Vector3d a_Pos);
// cEntity overrides:
virtual void OnRightClicked(cPlayer & a_Player) override;
@ -201,12 +211,12 @@ private:
class cMinecartWithTNT :
public cMinecart
{
typedef cMinecart super;
using super = cMinecart;
public:
CLASS_PROTODEF(cMinecartWithTNT)
cMinecartWithTNT(double a_X, double a_Y, double a_Z);
cMinecartWithTNT(Vector3d a_Pos);
} ;
@ -216,10 +226,11 @@ public:
class cMinecartWithHopper :
public cMinecart
{
typedef cMinecart super;
using super = cMinecart;
public:
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)
: cHangingEntity(etPainting, a_Direction, a_X, a_Y, a_Z),
cPainting::cPainting(const AString & a_Name, eBlockFace a_Direction, Vector3d a_Pos):
super(etPainting, a_Direction, a_Pos),
m_Name(a_Name)
{
}

View File

@ -11,15 +11,15 @@
class cPainting :
public cHangingEntity
{
typedef cHangingEntity super;
public:
// tolua_end
using super = cHangingEntity;
public: // tolua_export
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 */
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) :
super(a_EntityType, 0, 0, 0, a_Width, a_Height),
super(a_EntityType, Vector3d(), a_Width, a_Height),
m_EntityEffects(tEffectMap()),
m_LastGroundHeight(0),
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)
, m_Timer(0)
, m_Item(a_Item)
, m_bCollected(false)
, m_bIsPlayerCreated(IsPlayerCreated)
, m_bCanCombine(a_CanCombine)
, m_Lifetime(cTickTime(a_LifetimeTicks))
////////////////////////////////////////////////////////////////////////////////
// cPickup:
cPickup::cPickup(Vector3d a_Pos, const cItem & a_Item, bool IsPlayerCreated, Vector3f a_Speed, int a_LifetimeTicks, bool a_CanCombine):
super(etPickup, a_Pos, 0.2, 0.2),
m_Timer(0),
m_Item(a_Item),
m_bCollected(false),
m_bIsPlayerCreated(IsPlayerCreated),
m_bCanCombine(a_CanCombine),
m_Lifetime(cTickTime(a_LifetimeTicks))
{
SetGravity(-16.0f);
SetAirDrag(0.02f);
SetMaxHealth(5);
SetHealth(5);
SetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ);
SetSpeed(a_Speed);
}

View File

@ -18,14 +18,15 @@ class cPlayer;
class cPickup :
public cEntity
{
typedef cEntity super;
public:
// tolua_end
using super = cEntity;
public: // tolua_export
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
const cItem & GetItem(void) const {return m_Item; }

View File

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

View File

@ -20,9 +20,15 @@
class cProjectileEntity :
public cEntity
{
typedef cEntity super;
// tolua_end
using super = cEntity;
// tolua_begin
public:
/** The kind of the projectile. The numbers correspond to the network type ID used for spawning them in the protocol. */
enum eKind
{
@ -43,10 +49,32 @@ public:
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, const Vector3d & a_Pos, const Vector3d & a_Speed, 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, 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 */
virtual void OnHitSolidBlock(Vector3d a_HitPos, eBlockFace a_HitFace);

View File

@ -21,11 +21,11 @@
cSplashPotionEntity::cSplashPotionEntity(
cEntity * a_Creator,
double a_X, double a_Y, double a_Z,
const Vector3d & a_Speed,
Vector3d a_Pos,
Vector3d a_Speed,
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_DestroyTimer(-1)
{

View File

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

View File

@ -9,7 +9,7 @@
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)
{
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) :
super(pkEgg, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25),
cThrownEggEntity::cThrownEggEntity(cEntity * a_Creator, Vector3d a_Pos, Vector3d a_Speed):
super(pkEgg, a_Creator, a_Pos, 0.25, 0.25),
m_DestroyTimer(-1)
{
SetSpeed(a_Speed);

View File

@ -20,15 +20,15 @@
class cThrownEggEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
public:
// tolua_end
using super = cProjectileEntity;
public: // tolua_export
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:

View File

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

View File

@ -20,15 +20,15 @@
class cThrownEnderPearlEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
public:
// tolua_end
using super = cProjectileEntity;
public: // tolua_export
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:

View File

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

View File

@ -20,15 +20,15 @@
class cThrownSnowballEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
public:
// tolua_end
using super = cProjectileEntity;
public: // tolua_export
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:

View File

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

View File

@ -20,15 +20,15 @@
class cWitherSkullEntity :
public cProjectileEntity
{
typedef cProjectileEntity super;
public:
// tolua_end
using super = cProjectileEntity;
public: // tolua_export
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:

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;
// 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)
{
// No block entity for this block type

View File

@ -228,9 +228,9 @@ public:
FloaterPos.y += 0.5f;
const float FISH_SPEED_MULT = 2.25f;
Vector3d FlyDirection = a_Player->GetEyePosition() - FloaterPos;
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->SpawnExperienceOrb(a_Player->GetPosX(), a_Player->GetPosY(), a_Player->GetPosZ(), Random.RandInt(1, 6));
Vector3d FlyDirection = (a_Player->GetEyePosition() - FloaterPos).addedY(1.0f) * FISH_SPEED_MULT;
a_World->SpawnItemPickups(Drops, FloaterPos, FlyDirection);
a_World->SpawnExperienceOrb(a_Player->GetPosition(), Random.RandInt(1, 6));
a_Player->UseEquippedItem(1);
cRoot::Get()->GetPluginManager()->CallHookPlayerFished(*a_Player, Drops);
}
@ -245,7 +245,7 @@ public:
}
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();
if (!FloaterPtr->Initialize(std::move(Floater), *a_World))
{

View File

@ -38,7 +38,7 @@ public:
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();
if (!ItemFramePtr->Initialize(std::move(ItemFrame), *a_World))
{

View File

@ -70,7 +70,7 @@ public:
{ "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();
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;
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();
if (!FireChargePtr->Initialize(std::move(FireCharge), *m_World))
{

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