Netherportal fix

make it possible to light a netherportal when there is a obsidian next to the portal (see issue: #960)

added new function to check if a portal frame is valid and can possibly fil in the frame
added check if two portalframes are posible and then checks both
This commit is contained in:
Us3ful-dev 2026-03-09 10:50:57 +01:00
parent b3ff7f5998
commit b6e1a0a38d
2 changed files with 79 additions and 40 deletions

View file

@ -11,7 +11,7 @@ PortalTile::PortalTile(int id) : HalfTransparentTile(id, L"portal", Material::po
setTicking(true); setTicking(true);
} }
void PortalTile::tick(Level *level, int x, int y, int z, Random *random) void PortalTile::tick(Level* level, int x, int y, int z, Random* random)
{ {
HalfTransparentTile::tick(level, x, y, z, random); HalfTransparentTile::tick(level, x, y, z, random);
@ -28,7 +28,7 @@ void PortalTile::tick(Level *level, int x, int y, int z, Random *random)
// spawn a pig man here // spawn a pig man here
int iResult = 0; int iResult = 0;
shared_ptr<Entity> entity = SpawnEggItem::spawnMobAt(level, 57, x + .5, y0 + 1.1, z + .5, &iResult); shared_ptr<Entity> entity = SpawnEggItem::spawnMobAt(level, 57, x + .5, y0 + 1.1, z + .5, &iResult);
if (entity != NULL) if (entity != nullptr)
{ {
entity->changingDimensionDelay = entity->getDimensionChangingDelay(); entity->changingDimensionDelay = entity->getDimensionChangingDelay();
} }
@ -36,12 +36,12 @@ void PortalTile::tick(Level *level, int x, int y, int z, Random *random)
} }
} }
AABB *PortalTile::getAABB(Level *level, int x, int y, int z) AABB* PortalTile::getAABB(Level* level, int x, int y, int z)
{ {
return NULL; return nullptr;
} }
void PortalTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr<TileEntity> forceEntity) // 4J added forceData, forceEntity param void PortalTile::updateShape(LevelSource* level, int x, int y, int z, int forceData, shared_ptr<TileEntity> forceEntity) // 4J added forceData, forceEntity param
{ {
if (level->getTile(x - 1, y, z) == id || level->getTile(x + 1, y, z) == id) if (level->getTile(x - 1, y, z) == id || level->getTile(x + 1, y, z) == id)
{ {
@ -67,21 +67,8 @@ bool PortalTile::isCubeShaped()
return false; return false;
} }
bool PortalTile::trySpawnPortal(Level *level, int x, int y, int z, bool actuallySpawn) bool PortalTile::validPortalFrame(Level* level, int x, int y, int z, int xd, int zd, bool actuallySpawn)
{ {
int xd = 0;
int zd = 0;
if (level->getTile(x - 1, y, z) == Tile::obsidian_Id || level->getTile(x + 1, y, z) == Tile::obsidian_Id) xd = 1;
if (level->getTile(x, y, z - 1) == Tile::obsidian_Id || level->getTile(x, y, z + 1) == Tile::obsidian_Id) zd = 1;
if (xd == zd) return false;
if (level->getTile(x - xd, y, z - zd) == 0)
{
x -= xd;
z -= zd;
}
for (int xx = -1; xx <= 2; xx++) for (int xx = -1; xx <= 2; xx++)
{ {
for (int yy = -1; yy <= 3; yy++) for (int yy = -1; yy <= 3; yy++)
@ -102,7 +89,7 @@ bool PortalTile::trySpawnPortal(Level *level, int x, int y, int z, bool actually
} }
} }
if( !actuallySpawn ) if (!actuallySpawn)
return true; return true;
for (int xx = 0; xx < 2; xx++) for (int xx = 0; xx < 2; xx++)
@ -114,10 +101,61 @@ bool PortalTile::trySpawnPortal(Level *level, int x, int y, int z, bool actually
} }
return true; return true;
}
bool PortalTile::trySpawnPortal(Level* level, int x, int y, int z, bool actuallySpawn)
{
int xd = 0;
int zd = 0;
if (level->getTile(x - 1, y, z) == Tile::obsidian_Id || level->getTile(x + 1, y, z) == Tile::obsidian_Id) xd = 1;
if (level->getTile(x, y, z - 1) == Tile::obsidian_Id || level->getTile(x, y, z + 1) == Tile::obsidian_Id) zd = 1;
bool twoPosible = false; // two neth portals posible (x and z direction)
if (xd == zd)
{
if (xd == 1) twoPosible = true;
else return false;
}
bool changedx = false; // changed x so it can be reverted if two portals are posible
if (level->getTile(x - xd, y, z) == 0)
{
level->setTileAndData(x, y + 6, z, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS);
changedx = true;
x--;
}
else if (level->getTile(x, y, z - zd) == 0)
{
level->setTileAndData(x, y + 7, z, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS);
z--;
}
if (!twoPosible)
{
if (!PortalTile::validPortalFrame(level, x, y, z, xd, zd, actuallySpawn)) return false;
}
else
{
if (!PortalTile::validPortalFrame(level, x, y, z, xd, 0, actuallySpawn))
{
if (level->getTile(x, y, z - zd) == 0)
{
level->setTileAndData(x, y + 7, z, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS);
z--;
}
if (changedx) x++;
if (!PortalTile::validPortalFrame(level, x, y, z, 0, zd, actuallySpawn))
{
return false;
}
}
}
return true;
} }
void PortalTile::neighborChanged(Level *level, int x, int y, int z, int type) void PortalTile::neighborChanged(Level* level, int x, int y, int z, int type)
{ {
int xd = 0; int xd = 0;
int zd = 1; int zd = 1;
@ -166,7 +204,7 @@ void PortalTile::neighborChanged(Level *level, int x, int y, int z, int type)
} }
bool PortalTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face) bool PortalTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face)
{ {
if (level->getTile(x, y, z) == id) return false; if (level->getTile(x, y, z) == id) return false;
@ -187,7 +225,7 @@ bool PortalTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int f
return false; return false;
} }
int PortalTile::getResourceCount(Random *random) int PortalTile::getResourceCount(Random* random)
{ {
return 0; return 0;
} }
@ -197,14 +235,14 @@ int PortalTile::getRenderLayer()
return 1; return 1;
} }
void PortalTile::entityInside(Level *level, int x, int y, int z, shared_ptr<Entity> entity) void PortalTile::entityInside(Level* level, int x, int y, int z, shared_ptr<Entity> entity)
{ {
if (entity->GetType() == eTYPE_EXPERIENCEORB ) return; // 4J added if (entity->GetType() == eTYPE_EXPERIENCEORB) return; // 4J added
if (entity->riding == NULL && entity->rider.lock() == NULL) entity->handleInsidePortal(); if (entity->riding == nullptr && entity->rider.lock() == nullptr) entity->handleInsidePortal();
} }
void PortalTile::animateTick(Level *level, int xt, int yt, int zt, Random *random) void PortalTile::animateTick(Level* level, int xt, int yt, int zt, Random* random)
{ {
if (random->nextInt(100) == 0) if (random->nextInt(100) == 0)
{ {
@ -237,7 +275,7 @@ void PortalTile::animateTick(Level *level, int xt, int yt, int zt, Random *rando
} }
} }
int PortalTile::cloneTileId(Level *level, int x, int y, int z) int PortalTile::cloneTileId(Level* level, int x, int y, int z)
{ {
return 0; return 0;
} }

View file

@ -7,19 +7,20 @@ class Random;
class PortalTile : public HalfTransparentTile class PortalTile : public HalfTransparentTile
{ {
public: public:
PortalTile(int id); PortalTile(int id);
virtual void tick(Level *level, int x, int y, int z, Random *random); virtual void tick(Level* level, int x, int y, int z, Random* random);
virtual AABB *getAABB(Level *level, int x, int y, int z); virtual AABB* getAABB(Level* level, int x, int y, int z);
virtual void updateShape(LevelSource *level, int x, int y, int z, int forceData = -1, shared_ptr<TileEntity> forceEntity = shared_ptr<TileEntity>()); // 4J added forceData, forceEntity param virtual void updateShape(LevelSource* level, int x, int y, int z, int forceData = -1, shared_ptr<TileEntity> forceEntity = shared_ptr<TileEntity>()); // 4J added forceData, forceEntity param
virtual bool isSolidRender(bool isServerLevel = false); virtual bool isSolidRender(bool isServerLevel = false);
virtual bool isCubeShaped(); virtual bool isCubeShaped();
virtual bool trySpawnPortal(Level *level, int x, int y, int z, bool actuallySpawn); virtual bool validPortalFrame(Level* level, int x, int y, int z, int xd, int zd, bool actuallySpawn);
virtual void neighborChanged(Level *level, int x, int y, int z, int type); virtual bool trySpawnPortal(Level* level, int x, int y, int z, bool actuallySpawn);
virtual bool shouldRenderFace(LevelSource *level, int x, int y, int z, int face); virtual void neighborChanged(Level* level, int x, int y, int z, int type);
virtual int getResourceCount(Random *random); virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face);
virtual int getResourceCount(Random* random);
virtual int getRenderLayer(); virtual int getRenderLayer();
virtual void entityInside(Level *level, int x, int y, int z, shared_ptr<Entity> entity); virtual void entityInside(Level* level, int x, int y, int z, shared_ptr<Entity> entity);
virtual void animateTick(Level *level, int xt, int yt, int zt, Random *random); virtual void animateTick(Level* level, int xt, int yt, int zt, Random* random);
virtual int cloneTileId(Level *level, int x, int y, int z); virtual int cloneTileId(Level* level, int x, int y, int z);
virtual bool mayPick(); // 4J Added override virtual bool mayPick(); // 4J Added override
}; };