chore: format Minecraft.World

This commit is contained in:
Tropical
2026-03-13 17:06:56 -05:00
parent bd6284025d
commit 33d0737d1d
1511 changed files with 108661 additions and 115521 deletions

View File

@@ -20,37 +20,29 @@ const std::wstring PistonBaseTile::INSIDE_TEX = L"piston_inner_top";
const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f;
namespace
{
namespace {
#if defined(_WIN32)
inline void *PistonTlsGetValue(DWORD key)
{
return TlsGetValue(key);
}
inline void* PistonTlsGetValue(DWORD key) { return TlsGetValue(key); }
inline void PistonTlsSetValue(DWORD key, void *value)
{
TlsSetValue(key, value);
}
#else
pthread_key_t CreatePistonTlsKey()
{
pthread_key_t key;
pthread_key_create(&key, NULL);
return key;
}
inline void *PistonTlsGetValue(pthread_key_t key)
{
return pthread_getspecific(key);
}
inline void PistonTlsSetValue(pthread_key_t key, void *value)
{
pthread_setspecific(key, value);
}
#endif
inline void PistonTlsSetValue(DWORD key, void* value) {
TlsSetValue(key, value);
}
#else
pthread_key_t CreatePistonTlsKey() {
pthread_key_t key;
pthread_key_create(&key, NULL);
return key;
}
inline void* PistonTlsGetValue(pthread_key_t key) {
return pthread_getspecific(key);
}
inline void PistonTlsSetValue(pthread_key_t key, void* value) {
pthread_setspecific(key, value);
}
#endif
} // namespace
#if defined(_WIN32)
DWORD PistonBaseTile::tlsIdx = TlsAlloc();
@@ -58,181 +50,172 @@ DWORD PistonBaseTile::tlsIdx = TlsAlloc();
pthread_key_t PistonBaseTile::tlsIdx = CreatePistonTlsKey();
#endif
// 4J - NOTE - this ignoreUpdate stuff has been removed from the java version, but I'm not currently sure how the java version does without it... there must be
// some other mechanism that we don't have that stops the event from one piston being processed, from causing neighbours to have extra events created for them.
// For us, that means that if we create a piston next to another one, then one of them gets two events to createPush, the second of which fails, leaving the
// piston in a bad (simultaneously extended & not extended) state.
// 4J - ignoreUpdate is a static in java, implementing as TLS here to make thread safe
bool PistonBaseTile::ignoreUpdate()
{
return PistonTlsGetValue(tlsIdx) != NULL;
// 4J - NOTE - this ignoreUpdate stuff has been removed from the java version,
// but I'm not currently sure how the java version does without it... there must
// be some other mechanism that we don't have that stops the event from one
// piston being processed, from causing neighbours to have extra events created
// for them. For us, that means that if we create a piston next to another one,
// then one of them gets two events to createPush, the second of which fails,
// leaving the piston in a bad (simultaneously extended & not extended) state.
// 4J - ignoreUpdate is a static in java, implementing as TLS here to make
// thread safe
bool PistonBaseTile::ignoreUpdate() {
return PistonTlsGetValue(tlsIdx) != NULL;
}
void PistonBaseTile::ignoreUpdate(bool set)
{
PistonTlsSetValue(tlsIdx, reinterpret_cast<void *>(static_cast<intptr_t>(set ? 1 : 0)));
void PistonBaseTile::ignoreUpdate(bool set) {
PistonTlsSetValue(
tlsIdx, reinterpret_cast<void*>(static_cast<intptr_t>(set ? 1 : 0)));
}
PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, false)
{
// 4J - added initialiser
ignoreUpdate(false);
PistonBaseTile::PistonBaseTile(int id, bool isSticky)
: Tile(id, Material::piston, false) {
// 4J - added initialiser
ignoreUpdate(false);
this->isSticky = isSticky;
setSoundType(SOUND_STONE);
setDestroyTime(0.5f);
iconInside = NULL;
iconBack = NULL;
iconPlatform = NULL;
iconInside = NULL;
iconBack = NULL;
iconPlatform = NULL;
}
Icon *PistonBaseTile::getPlatformTexture()
{
return iconPlatform;
Icon* PistonBaseTile::getPlatformTexture() { return iconPlatform; }
void PistonBaseTile::updateShape(float x0, float y0, float z0, float x1,
float y1, float z1) {
setShape(x0, y0, z0, x1, y1, z1);
}
void PistonBaseTile::updateShape(float x0, float y0, float z0, float x1, float y1, float z1)
{
setShape(x0, y0, z0, x1, y1, z1);
}
Icon *PistonBaseTile::getTexture(int face, int data)
{
Icon* PistonBaseTile::getTexture(int face, int data) {
int facing = getFacing(data);
if (facing > 5)
{
if (facing > 5) {
return iconPlatform;
}
if (face == facing)
{
if (face == facing) {
// sorry about this mess...
// when the piston is extended, either normally
// or because a piston arm animation, the top
// texture is the furnace bottom
ThreadStorage *tls = (ThreadStorage *)TlsGetValue(Tile::tlsIdxShape);
if (isExtended(data) || tls->xx0 > 0 || tls->yy0 > 0 || tls->zz0 > 0 || tls->xx1 < 1 || tls->yy1 < 1 || tls->zz1 < 1)
{
ThreadStorage* tls = (ThreadStorage*)TlsGetValue(Tile::tlsIdxShape);
if (isExtended(data) || tls->xx0 > 0 || tls->yy0 > 0 || tls->zz0 > 0 ||
tls->xx1 < 1 || tls->yy1 < 1 || tls->zz1 < 1) {
return iconInside;
}
return iconPlatform;
}
if (face == Facing::OPPOSITE_FACING[facing])
{
if (face == Facing::OPPOSITE_FACING[facing]) {
return iconBack;
}
return icon;
}
Icon *PistonBaseTile::getTexture(const std::wstring &name)
{
if (name.compare(EDGE_TEX) == 0) return Tile::pistonBase->icon;
if (name.compare(PLATFORM_TEX) == 0) return Tile::pistonBase->iconPlatform;
if (name.compare(PLATFORM_STICKY_TEX) == 0) return Tile::pistonStickyBase->iconPlatform;
if (name.compare(INSIDE_TEX) == 0) return Tile::pistonBase->iconInside;
Icon* PistonBaseTile::getTexture(const std::wstring& name) {
if (name.compare(EDGE_TEX) == 0) return Tile::pistonBase->icon;
if (name.compare(PLATFORM_TEX) == 0) return Tile::pistonBase->iconPlatform;
if (name.compare(PLATFORM_STICKY_TEX) == 0)
return Tile::pistonStickyBase->iconPlatform;
if (name.compare(INSIDE_TEX) == 0) return Tile::pistonBase->iconInside;
return NULL;
return NULL;
}
//@Override
void PistonBaseTile::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(EDGE_TEX);
iconPlatform = iconRegister->registerIcon(isSticky ? PLATFORM_STICKY_TEX : PLATFORM_TEX);
iconInside = iconRegister->registerIcon(INSIDE_TEX);
iconBack = iconRegister->registerIcon(BACK_TEX);
void PistonBaseTile::registerIcons(IconRegister* iconRegister) {
icon = iconRegister->registerIcon(EDGE_TEX);
iconPlatform = iconRegister->registerIcon(isSticky ? PLATFORM_STICKY_TEX
: PLATFORM_TEX);
iconInside = iconRegister->registerIcon(INSIDE_TEX);
iconBack = iconRegister->registerIcon(BACK_TEX);
}
int PistonBaseTile::getRenderShape()
int PistonBaseTile::getRenderShape() { return SHAPE_PISTON_BASE; }
bool PistonBaseTile::isSolidRender(bool isServerLevel) { return false; }
bool PistonBaseTile::use(Level* level, int x, int y, int z,
std::shared_ptr<Player> player, int clickedFace,
float clickX, float clickY, float clickZ,
bool soundOnly /*=false*/) // 4J added soundOnly param
{
return SHAPE_PISTON_BASE;
return false;
}
bool PistonBaseTile::isSolidRender(bool isServerLevel)
{
return false;
}
bool PistonBaseTile::use(Level *level, int x, int y, int z, std::shared_ptr<Player> player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly/*=false*/) // 4J added soundOnly param
{
return false;
}
void PistonBaseTile::setPlacedBy(Level *level, int x, int y, int z, std::shared_ptr<Mob> by)
{
int targetData = getNewFacing(level, x, y, z, std::dynamic_pointer_cast<Player>(by) );
void PistonBaseTile::setPlacedBy(Level* level, int x, int y, int z,
std::shared_ptr<Mob> by) {
int targetData =
getNewFacing(level, x, y, z, std::dynamic_pointer_cast<Player>(by));
level->setData(x, y, z, targetData);
if (!level->isClientSide && !ignoreUpdate())
{
if (!level->isClientSide && !ignoreUpdate()) {
checkIfExtend(level, x, y, z);
}
}
void PistonBaseTile::neighborChanged(Level *level, int x, int y, int z, int type)
{
if (!level->isClientSide && !ignoreUpdate())
{
void PistonBaseTile::neighborChanged(Level* level, int x, int y, int z,
int type) {
if (!level->isClientSide && !ignoreUpdate()) {
checkIfExtend(level, x, y, z);
}
}
void PistonBaseTile::onPlace(Level *level, int x, int y, int z)
{
if (!level->isClientSide && level->getTileEntity(x, y, z) == NULL && !ignoreUpdate())
{
void PistonBaseTile::onPlace(Level* level, int x, int y, int z) {
if (!level->isClientSide && level->getTileEntity(x, y, z) == NULL &&
!ignoreUpdate()) {
checkIfExtend(level, x, y, z);
}
}
void PistonBaseTile::checkIfExtend(Level *level, int x, int y, int z)
{
void PistonBaseTile::checkIfExtend(Level* level, int x, int y, int z) {
int data = level->getData(x, y, z);
int facing = getFacing(data);
if (facing == UNDEFINED_FACING)
{
if (facing == UNDEFINED_FACING) {
return;
}
bool extend = getNeighborSignal(level, x, y, z, facing);
if (extend && !isExtended(data))
{
if (canPush(level, x, y, z, facing))
{
//level->setDataNoUpdate(x, y, z, facing | EXTENDED_BIT);
if (extend && !isExtended(data)) {
if (canPush(level, x, y, z, facing)) {
// level->setDataNoUpdate(x, y, z, facing | EXTENDED_BIT);
level->tileEvent(x, y, z, id, TRIGGER_EXTEND, facing);
}
}
else if (!extend && isExtended(data))
{
//level->setDataNoUpdate(x, y, z, facing);
} else if (!extend && isExtended(data)) {
// level->setDataNoUpdate(x, y, z, facing);
level->tileEvent(x, y, z, id, TRIGGER_CONTRACT, facing);
}
}
/**
* This method checks neighbor signals for this block and the block above,
* and directly beneath. However, it avoids checking blocks that would be
* pushed by this block.
*
* @param level
* @param x
* @param y
* @param z
* @return
*/
bool PistonBaseTile::getNeighborSignal(Level *level, int x, int y, int z, int facing)
{
* This method checks neighbor signals for this block and the block above,
* and directly beneath. However, it avoids checking blocks that would be
* pushed by this block.
*
* @param level
* @param x
* @param y
* @param z
* @return
*/
bool PistonBaseTile::getNeighborSignal(Level* level, int x, int y, int z,
int facing) {
// check adjacent neighbors, but not in push direction
if (facing != Facing::DOWN && level->getSignal(x, y - 1, z, Facing::DOWN)) return true;
if (facing != Facing::UP && level->getSignal(x, y + 1, z, Facing::UP)) return true;
if (facing != Facing::NORTH && level->getSignal(x, y, z - 1, Facing::NORTH)) return true;
if (facing != Facing::SOUTH && level->getSignal(x, y, z + 1, Facing::SOUTH)) return true;
if (facing != Facing::EAST && level->getSignal(x + 1, y, z, Facing::EAST)) return true;
if (facing != Facing::WEST && level->getSignal(x - 1, y, z, Facing::WEST)) return true;
if (facing != Facing::DOWN && level->getSignal(x, y - 1, z, Facing::DOWN))
return true;
if (facing != Facing::UP && level->getSignal(x, y + 1, z, Facing::UP))
return true;
if (facing != Facing::NORTH && level->getSignal(x, y, z - 1, Facing::NORTH))
return true;
if (facing != Facing::SOUTH && level->getSignal(x, y, z + 1, Facing::SOUTH))
return true;
if (facing != Facing::EAST && level->getSignal(x + 1, y, z, Facing::EAST))
return true;
if (facing != Facing::WEST && level->getSignal(x - 1, y, z, Facing::WEST))
return true;
// check signals above
if (level->getSignal(x, y, z, 0)) return true;
@@ -245,63 +228,73 @@ bool PistonBaseTile::getNeighborSignal(Level *level, int x, int y, int z, int fa
return false;
}
void PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1, int facing)
{
ignoreUpdate(true);
void PistonBaseTile::triggerEvent(Level* level, int x, int y, int z, int param1,
int facing) {
ignoreUpdate(true);
if (param1 == TRIGGER_EXTEND)
{
level->setDataNoUpdate(x, y, z, facing | EXTENDED_BIT);
}
else
{
level->setDataNoUpdate(x, y, z, facing);
}
if (param1 == TRIGGER_EXTEND)
{
PIXBeginNamedEvent(0,"Create push\n");
if (createPush(level, x, y, z, facing))
{
// 4J - it is (currently) critical that this setData sends data to the client, so have added a bool to the method so that it sends data even if the data was already set to the same value
// as before, which was actually its behaviour until a change in 1.0.1 meant that setData only conditionally sent updates to listeners. If the data update Isn't sent, then what
// can happen is:
// (1) the host sends the tile event to the client
// (2) the client gets the tile event, and sets the tile/data value locally.
// (3) just before setting the tile/data locally, the client will put the old value in the vector of things to be restored should an update not be received back from the host
// (4) we don't get any update of the tile from the host, and so the old value gets restored on the client
// (5) the piston base ends up being restored to its retracted state whilst the piston arm is extended
// We really need to spend some time investigating a better way for pistons to work as it all seems a bit scary how the host/client interact, but forcing this to send should at least
// restore the behaviour of the pistons to something closer to what they were before the 1.0.1 update. By sending this data update, then (4) in the list above doesn't happen
// because the client does actually receive an update for this tile from the host after the event has been processed on the cient.
level->setData(x, y, z, facing | EXTENDED_BIT, true);
level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_OUT, 0.5f, level->random->nextFloat() * 0.25f + 0.6f);
}
else
{
level->setDataNoUpdate(x, y, z, facing);
}
PIXEndNamedEvent();
if (param1 == TRIGGER_EXTEND) {
level->setDataNoUpdate(x, y, z, facing | EXTENDED_BIT);
} else {
level->setDataNoUpdate(x, y, z, facing);
}
else if (param1 == TRIGGER_CONTRACT)
{
PIXBeginNamedEvent(0,"Contract phase A\n");
std::shared_ptr<TileEntity> prevTileEntity = level->getTileEntity(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]);
if (prevTileEntity != NULL && std::dynamic_pointer_cast<PistonPieceEntity>(prevTileEntity) != NULL)
{
std::dynamic_pointer_cast<PistonPieceEntity>(prevTileEntity)->finalTick();
if (param1 == TRIGGER_EXTEND) {
PIXBeginNamedEvent(0, "Create push\n");
if (createPush(level, x, y, z, facing)) {
// 4J - it is (currently) critical that this setData sends data to
// the client, so have added a bool to the method so that it sends
// data even if the data was already set to the same value as
// before, which was actually its behaviour until a change in 1.0.1
// meant that setData only conditionally sent updates to listeners.
// If the data update Isn't sent, then what can happen is: (1) the
// host sends the tile event to the client (2) the client gets the
// tile event, and sets the tile/data value locally. (3) just before
// setting the tile/data locally, the client will put the old value
// in the vector of things to be restored should an update not be
// received back from the host (4) we don't get any update of the
// tile from the host, and so the old value gets restored on the
// client (5) the piston base ends up being restored to its
// retracted state whilst the piston arm is extended We really need
// to spend some time investigating a better way for pistons to work
// as it all seems a bit scary how the host/client interact, but
// forcing this to send should at least restore the behaviour of the
// pistons to something closer to what they were before the 1.0.1
// update. By sending this data update, then (4) in the list above
// doesn't happen because the client does actually receive an update
// for this tile from the host after the event has been processed on
// the cient.
level->setData(x, y, z, facing | EXTENDED_BIT, true);
level->playSound(x + 0.5, y + 0.5, z + 0.5,
eSoundType_TILE_PISTON_OUT, 0.5f,
level->random->nextFloat() * 0.25f + 0.6f);
} else {
level->setDataNoUpdate(x, y, z, facing);
}
PIXEndNamedEvent();
} else if (param1 == TRIGGER_CONTRACT) {
PIXBeginNamedEvent(0, "Contract phase A\n");
std::shared_ptr<TileEntity> prevTileEntity = level->getTileEntity(
x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing],
z + Facing::STEP_Z[facing]);
if (prevTileEntity != NULL &&
std::dynamic_pointer_cast<PistonPieceEntity>(prevTileEntity) !=
NULL) {
std::dynamic_pointer_cast<PistonPieceEntity>(prevTileEntity)
->finalTick();
}
stopSharingIfServer(level, x, y, z); // 4J added
level->setTileAndDataNoUpdate(x, y, z, Tile::pistonMovingPiece_Id, facing);
level->setTileEntity(x, y, z, PistonMovingPiece::newMovingPieceEntity(id, facing, facing, false, true));
stopSharingIfServer(level, x, y, z); // 4J added
level->setTileAndDataNoUpdate(x, y, z, Tile::pistonMovingPiece_Id,
facing);
level->setTileEntity(x, y, z,
PistonMovingPiece::newMovingPieceEntity(
id, facing, facing, false, true));
PIXEndNamedEvent();
PIXEndNamedEvent();
// sticky movement
if (isSticky)
{
PIXBeginNamedEvent(0,"Contract sticky phase A\n");
if (isSticky) {
PIXBeginNamedEvent(0, "Contract sticky phase A\n");
int twoX = x + Facing::STEP_X[facing] * 2;
int twoY = y + Facing::STEP_Y[facing] * 2;
int twoZ = z + Facing::STEP_Z[facing] * 2;
@@ -309,21 +302,23 @@ void PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
int blockData = level->getData(twoX, twoY, twoZ);
bool pistonPiece = false;
PIXEndNamedEvent();
PIXEndNamedEvent();
if (block == Tile::pistonMovingPiece_Id)
{
PIXBeginNamedEvent(0,"Contract sticky phase B\n");
if (block == Tile::pistonMovingPiece_Id) {
PIXBeginNamedEvent(0, "Contract sticky phase B\n");
// the block two steps away is a moving piston block piece,
// so replace it with the real data, since it's probably
// this piston which is changing too fast
std::shared_ptr<TileEntity> tileEntity = level->getTileEntity(twoX, twoY, twoZ);
if (tileEntity != NULL && std::dynamic_pointer_cast<PistonPieceEntity>(tileEntity) != NULL )
{
std::shared_ptr<PistonPieceEntity> ppe = std::dynamic_pointer_cast<PistonPieceEntity>(tileEntity);
std::shared_ptr<TileEntity> tileEntity =
level->getTileEntity(twoX, twoY, twoZ);
if (tileEntity != NULL &&
std::dynamic_pointer_cast<PistonPieceEntity>(tileEntity) !=
NULL) {
std::shared_ptr<PistonPieceEntity> ppe =
std::dynamic_pointer_cast<PistonPieceEntity>(
tileEntity);
if (ppe->getFacing() == facing && ppe->isExtending())
{
if (ppe->getFacing() == facing && ppe->isExtending()) {
// force the tile to air before pushing
ppe->finalTick();
block = ppe->getId();
@@ -331,129 +326,125 @@ void PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1,
pistonPiece = true;
}
}
PIXEndNamedEvent();
PIXEndNamedEvent();
}
PIXBeginNamedEvent(0,"Contract sticky phase C\n");
if (!pistonPiece && block > 0 && (isPushable(block, level, twoX, twoY, twoZ, false))
&& (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_NORMAL || block == Tile::pistonBase_Id || block == Tile::pistonStickyBase_Id))
{
stopSharingIfServer(level, twoX, twoY, twoZ); // 4J added
PIXBeginNamedEvent(0, "Contract sticky phase C\n");
if (!pistonPiece && block > 0 &&
(isPushable(block, level, twoX, twoY, twoZ, false)) &&
(Tile::tiles[block]->getPistonPushReaction() ==
Material::PUSH_NORMAL ||
block == Tile::pistonBase_Id ||
block == Tile::pistonStickyBase_Id)) {
stopSharingIfServer(level, twoX, twoY, twoZ); // 4J added
x += Facing::STEP_X[facing];
y += Facing::STEP_Y[facing];
z += Facing::STEP_Z[facing];
level->setTileAndDataNoUpdate(x, y, z, Tile::pistonMovingPiece_Id, blockData);
level->setTileEntity(x, y, z, PistonMovingPiece::newMovingPieceEntity(block, blockData, facing, false, false));
level->setTileAndDataNoUpdate(
x, y, z, Tile::pistonMovingPiece_Id, blockData);
level->setTileEntity(
x, y, z,
PistonMovingPiece::newMovingPieceEntity(
block, blockData, facing, false, false));
ignoreUpdate(false);
ignoreUpdate(false);
level->setTile(twoX, twoY, twoZ, 0);
ignoreUpdate(true);
}
else if (!pistonPiece)
{
stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added
ignoreUpdate(false);
level->setTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing], 0);
ignoreUpdate(true);
ignoreUpdate(true);
} else if (!pistonPiece) {
stopSharingIfServer(level, x + Facing::STEP_X[facing],
y + Facing::STEP_Y[facing],
z + Facing::STEP_Z[facing]); // 4J added
ignoreUpdate(false);
level->setTile(x + Facing::STEP_X[facing],
y + Facing::STEP_Y[facing],
z + Facing::STEP_Z[facing], 0);
ignoreUpdate(true);
}
PIXEndNamedEvent();
}
else
{
stopSharingIfServer(level, x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing]); // 4J added
ignoreUpdate(false);
level->setTile(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing], 0);
ignoreUpdate(true);
PIXEndNamedEvent();
} else {
stopSharingIfServer(level, x + Facing::STEP_X[facing],
y + Facing::STEP_Y[facing],
z + Facing::STEP_Z[facing]); // 4J added
ignoreUpdate(false);
level->setTile(x + Facing::STEP_X[facing],
y + Facing::STEP_Y[facing],
z + Facing::STEP_Z[facing], 0);
ignoreUpdate(true);
}
level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_IN, 0.5f, level->random->nextFloat() * 0.15f + 0.6f);
level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_TILE_PISTON_IN,
0.5f, level->random->nextFloat() * 0.15f + 0.6f);
}
ignoreUpdate(false);
ignoreUpdate(false);
}
void PistonBaseTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, std::shared_ptr<TileEntity> forceEntity) // 4J added forceData, forceEntity param
void PistonBaseTile::updateShape(
LevelSource* level, int x, int y, int z, int forceData,
std::shared_ptr<TileEntity>
forceEntity) // 4J added forceData, forceEntity param
{
int data = (forceData == -1 ) ? level->getData(x, y, z) : forceData;
int data = (forceData == -1) ? level->getData(x, y, z) : forceData;
if (isExtended(data))
{
if (isExtended(data)) {
const float thickness = PLATFORM_THICKNESS / 16.0f;
switch (getFacing(data))
{
case Facing::DOWN:
setShape(0, thickness, 0, 1, 1, 1);
break;
case Facing::UP:
setShape(0, 0, 0, 1, 1 - thickness, 1);
break;
case Facing::NORTH:
setShape(0, 0, thickness, 1, 1, 1);
break;
case Facing::SOUTH:
setShape(0, 0, 0, 1, 1, 1 - thickness);
break;
case Facing::WEST:
setShape(thickness, 0, 0, 1, 1, 1);
break;
case Facing::EAST:
setShape(0, 0, 0, 1 - thickness, 1, 1);
break;
switch (getFacing(data)) {
case Facing::DOWN:
setShape(0, thickness, 0, 1, 1, 1);
break;
case Facing::UP:
setShape(0, 0, 0, 1, 1 - thickness, 1);
break;
case Facing::NORTH:
setShape(0, 0, thickness, 1, 1, 1);
break;
case Facing::SOUTH:
setShape(0, 0, 0, 1, 1, 1 - thickness);
break;
case Facing::WEST:
setShape(thickness, 0, 0, 1, 1, 1);
break;
case Facing::EAST:
setShape(0, 0, 0, 1 - thickness, 1, 1);
break;
}
}
else
{
} else {
setShape(0, 0, 0, 1, 1, 1);
}
}
void PistonBaseTile::updateDefaultShape()
{
setShape(0, 0, 0, 1, 1, 1);
}
void PistonBaseTile::updateDefaultShape() { setShape(0, 0, 0, 1, 1, 1); }
void PistonBaseTile::addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, std::shared_ptr<Entity> source)
{
void PistonBaseTile::addAABBs(Level* level, int x, int y, int z, AABB* box,
AABBList* boxes, std::shared_ptr<Entity> source) {
setShape(0, 0, 0, 1, 1, 1);
Tile::addAABBs(level, x, y, z, box, boxes, source);
}
AABB *PistonBaseTile::getAABB(Level *level, int x, int y, int z)
{
updateShape(level, x, y, z);
return Tile::getAABB(level, x, y, z);
AABB* PistonBaseTile::getAABB(Level* level, int x, int y, int z) {
updateShape(level, x, y, z);
return Tile::getAABB(level, x, y, z);
}
bool PistonBaseTile::isCubeShaped()
{
return false;
}
bool PistonBaseTile::isCubeShaped() { return false; }
int PistonBaseTile::getFacing(int data)
{
return data & 0x7;
}
int PistonBaseTile::getFacing(int data) { return data & 0x7; }
bool PistonBaseTile::isExtended(int data)
{
return (data & EXTENDED_BIT) != 0;
}
bool PistonBaseTile::isExtended(int data) { return (data & EXTENDED_BIT) != 0; }
int PistonBaseTile::getNewFacing(Level *level, int x, int y, int z, std::shared_ptr<Player> player)
{
if (Mth::abs((float) player->x - x) < 2 && Mth::abs((float) player->z - z) < 2)
{
int PistonBaseTile::getNewFacing(Level* level, int x, int y, int z,
std::shared_ptr<Player> player) {
if (Mth::abs((float)player->x - x) < 2 &&
Mth::abs((float)player->z - z) < 2) {
// If the player is above the block, the slot is on the top
double py = player->y + 1.82 - player->heightOffset;
if (py - y > 2)
{
if (py - y > 2) {
return Facing::UP;
}
// If the player is below the block, the slot is on the bottom
if (y - py > 0)
{
if (y - py > 0) {
return Facing::DOWN;
}
}
@@ -466,89 +457,78 @@ int PistonBaseTile::getNewFacing(Level *level, int x, int y, int z, std::shared_
return 0;
}
bool PistonBaseTile::isPushable(int block, Level *level, int cx, int cy, int cz, bool allowDestroyable)
{
bool PistonBaseTile::isPushable(int block, Level* level, int cx, int cy, int cz,
bool allowDestroyable) {
// special case for obsidian
if (block == Tile::obsidian_Id)
{
if (block == Tile::obsidian_Id) {
return false;
}
if (block == Tile::pistonBase_Id || block == Tile::pistonStickyBase_Id)
{
if (block == Tile::pistonBase_Id || block == Tile::pistonStickyBase_Id) {
// special case for piston bases
if (isExtended(level->getData(cx, cy, cz)))
{
if (isExtended(level->getData(cx, cy, cz))) {
return false;
}
}
else
{
if (Tile::tiles[block]->getDestroySpeed(level, cx, cy, cz) == Tile::INDESTRUCTIBLE_DESTROY_TIME)
{
} else {
if (Tile::tiles[block]->getDestroySpeed(level, cx, cy, cz) ==
Tile::INDESTRUCTIBLE_DESTROY_TIME) {
return false;
}
if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_BLOCK)
{
if (Tile::tiles[block]->getPistonPushReaction() ==
Material::PUSH_BLOCK) {
return false;
}
if (!allowDestroyable && Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY)
{
if (!allowDestroyable && Tile::tiles[block]->getPistonPushReaction() ==
Material::PUSH_DESTROY) {
return false;
}
}
if( Tile::tiles[block]->isEntityTile() ) // 4J - java uses instanceof EntityTile here
{
// may not push tile entities
return false;
}
if (Tile::tiles[block]
->isEntityTile()) // 4J - java uses instanceof EntityTile here
{
// may not push tile entities
return false;
}
return true;
return true;
}
bool PistonBaseTile::canPush(Level *level, int sx, int sy, int sz, int facing)
{
bool PistonBaseTile::canPush(Level* level, int sx, int sy, int sz, int facing) {
int cx = sx + Facing::STEP_X[facing];
int cy = sy + Facing::STEP_Y[facing];
int cz = sz + Facing::STEP_Z[facing];
for (int i = 0; i < MAX_PUSH_DEPTH + 1; i++)
{
if (cy <= 0 || cy >= (Level::maxBuildHeight - 1))
{
for (int i = 0; i < MAX_PUSH_DEPTH + 1; i++) {
if (cy <= 0 || cy >= (Level::maxBuildHeight - 1)) {
// out of bounds
return false;
}
// 4J - added to also check for out of bounds in x/z for our finite world
int minXZ = - (level->dimension->getXZSize() * 16 ) / 2;
int maxXZ = (level->dimension->getXZSize() * 16 ) / 2 - 1;
if( ( cx <= minXZ ) || ( cx >= maxXZ ) || ( cz <= minXZ ) || ( cz >= maxXZ ) )
{
return false;
}
// 4J - added to also check for out of bounds in x/z for our finite
// world
int minXZ = -(level->dimension->getXZSize() * 16) / 2;
int maxXZ = (level->dimension->getXZSize() * 16) / 2 - 1;
if ((cx <= minXZ) || (cx >= maxXZ) || (cz <= minXZ) || (cz >= maxXZ)) {
return false;
}
int block = level->getTile(cx, cy, cz);
if (block == 0)
{
if (block == 0) {
break;
}
if (!isPushable(block, level, cx, cy, cz, true))
{
if (!isPushable(block, level, cx, cy, cz, true)) {
return false;
}
if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY)
{
if (Tile::tiles[block]->getPistonPushReaction() ==
Material::PUSH_DESTROY) {
break;
}
if (i == MAX_PUSH_DEPTH)
{
if (i == MAX_PUSH_DEPTH) {
// we've reached the maximum push depth
// without finding air or a breakable block
return false;
@@ -560,68 +540,61 @@ bool PistonBaseTile::canPush(Level *level, int sx, int sy, int sz, int facing)
}
return true;
}
void PistonBaseTile::stopSharingIfServer(Level *level, int x, int y, int z)
{
if( !level->isClientSide )
{
MultiPlayerLevel *clientLevel = Minecraft::GetInstance()->getLevel(level->dimension->id);
if( clientLevel )
{
LevelChunk *lc = clientLevel->getChunkAt( x, z );
lc->stopSharingTilesAndData();
}
}
void PistonBaseTile::stopSharingIfServer(Level* level, int x, int y, int z) {
if (!level->isClientSide) {
MultiPlayerLevel* clientLevel =
Minecraft::GetInstance()->getLevel(level->dimension->id);
if (clientLevel) {
LevelChunk* lc = clientLevel->getChunkAt(x, z);
lc->stopSharingTilesAndData();
}
}
}
bool PistonBaseTile::createPush(Level *level, int sx, int sy, int sz, int facing)
{
bool PistonBaseTile::createPush(Level* level, int sx, int sy, int sz,
int facing) {
int cx = sx + Facing::STEP_X[facing];
int cy = sy + Facing::STEP_Y[facing];
int cz = sz + Facing::STEP_Z[facing];
for (int i = 0; i < MAX_PUSH_DEPTH + 1; i++)
{
if (cy <= 0 || cy >= (Level::maxBuildHeight - 1))
{
for (int i = 0; i < MAX_PUSH_DEPTH + 1; i++) {
if (cy <= 0 || cy >= (Level::maxBuildHeight - 1)) {
// out of bounds
return false;
}
// 4J - added to also check for out of bounds in x/z for our finite world
int minXZ = - (level->dimension->getXZSize() * 16 ) / 2;
int maxXZ = (level->dimension->getXZSize() * 16 ) / 2 - 1;
if( ( cx <= minXZ ) || ( cx >= maxXZ ) || ( cz <= minXZ ) || ( cz >= maxXZ ) )
{
return false;
}
int block = level->getTile(cx, cy, cz);
if (block == 0)
{
break;
}
if (!isPushable(block, level, cx, cy, cz, true))
{
// 4J - added to also check for out of bounds in x/z for our finite
// world
int minXZ = -(level->dimension->getXZSize() * 16) / 2;
int maxXZ = (level->dimension->getXZSize() * 16) / 2 - 1;
if ((cx <= minXZ) || (cx >= maxXZ) || (cz <= minXZ) || (cz >= maxXZ)) {
return false;
}
if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY)
{
int block = level->getTile(cx, cy, cz);
if (block == 0) {
break;
}
if (!isPushable(block, level, cx, cy, cz, true)) {
return false;
}
if (Tile::tiles[block]->getPistonPushReaction() ==
Material::PUSH_DESTROY) {
// this block is destroyed when pushed
Tile::tiles[block]->spawnResources(level, cx, cy, cz, level->getData(cx, cy, cz), 0);
Tile::tiles[block]->spawnResources(level, cx, cy, cz,
level->getData(cx, cy, cz), 0);
// setting the tile to air is actually superflous, but
// helps vs multiplayer problems
stopSharingIfServer(level, cx, cy, cz); // 4J added
stopSharingIfServer(level, cx, cy, cz); // 4J added
level->setTile(cx, cy, cz, 0);
break;
}
if (i == MAX_PUSH_DEPTH)
{
if (i == MAX_PUSH_DEPTH) {
// we've reached the maximum push depth
// without finding air or a breakable block
return false;
@@ -632,9 +605,7 @@ bool PistonBaseTile::createPush(Level *level, int sx, int sy, int sz, int facing
cz += Facing::STEP_Z[facing];
}
while (cx != sx || cy != sy || cz != sz)
{
while (cx != sx || cy != sy || cz != sz) {
int nx = cx - Facing::STEP_X[facing];
int ny = cy - Facing::STEP_Y[facing];
int nz = cz - Facing::STEP_Z[facing];
@@ -642,17 +613,25 @@ bool PistonBaseTile::createPush(Level *level, int sx, int sy, int sz, int facing
int block = level->getTile(nx, ny, nz);
int data = level->getData(nx, ny, nz);
stopSharingIfServer(level, cx, cy, cz); // 4J added
stopSharingIfServer(level, cx, cy, cz); // 4J added
if (block == id && nx == sx && ny == sy && nz == sz)
{
level->setTileAndDataNoUpdate(cx, cy, cz, Tile::pistonMovingPiece_Id, facing | (isSticky ? PistonExtensionTile::STICKY_BIT : 0), false);
level->setTileEntity(cx, cy, cz, PistonMovingPiece::newMovingPieceEntity(Tile::pistonExtensionPiece_Id, facing | (isSticky ? PistonExtensionTile::STICKY_BIT : 0), facing, true, false));
}
else
{
level->setTileAndDataNoUpdate(cx, cy, cz, Tile::pistonMovingPiece_Id, data, false);
level->setTileEntity(cx, cy, cz, PistonMovingPiece::newMovingPieceEntity(block, data, facing, true, false));
if (block == id && nx == sx && ny == sy && nz == sz) {
level->setTileAndDataNoUpdate(
cx, cy, cz, Tile::pistonMovingPiece_Id,
facing | (isSticky ? PistonExtensionTile::STICKY_BIT : 0),
false);
level->setTileEntity(
cx, cy, cz,
PistonMovingPiece::newMovingPieceEntity(
Tile::pistonExtensionPiece_Id,
facing | (isSticky ? PistonExtensionTile::STICKY_BIT : 0),
facing, true, false));
} else {
level->setTileAndDataNoUpdate(
cx, cy, cz, Tile::pistonMovingPiece_Id, data, false);
level->setTileEntity(cx, cy, cz,
PistonMovingPiece::newMovingPieceEntity(
block, data, facing, true, false));
}
cx = nx;
@@ -661,5 +640,4 @@ bool PistonBaseTile::createPush(Level *level, int sx, int sy, int sz, int facing
}
return true;
}