4jcraft/Minecraft.World/Blocks/TripWireTile.cpp
Nikita Edel a006cc5aa0 uninitialized vptr
the vptr to isSolidRender() is not known before contruction of the Tile. Its true by default. if false, need to pass false. that is what i did. i verfied what isSolidRender() is in every file. and did exactly what isSolidRender() would return
2026-03-10 23:22:34 +01:00

222 lines
5.2 KiB
C++

#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.level.tile.h"
#include "../Headers/net.minecraft.world.phys.h"
#include "TripWireTile.h"
TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, false)
{
setShape(0, 0, 0, 1, 2.5f / 16.0f, 1);
this->setTicking(true);
}
int TripWireTile::getTickDelay(Level *level)
{
// 4J: Increased (x2); quick update caused problems with shared
// data between client and server.
return 20; // 10;
}
AABB *TripWireTile::getAABB(Level *level, int x, int y, int z)
{
return NULL;
}
bool TripWireTile::blocksLight()
{
return false;
}
bool TripWireTile::isSolidRender(bool isServerLevel)
{
return false;
}
bool TripWireTile::isCubeShaped()
{
return false;
}
int TripWireTile::getRenderLayer()
{
return 1;
}
int TripWireTile::getRenderShape()
{
return Tile::SHAPE_TRIPWIRE;
}
int TripWireTile::getResource(int data, Random *random, int playerBonusLevel)
{
return Item::string_Id;
}
int TripWireTile::cloneTileId(Level *level, int x, int y, int z)
{
return Item::string_Id;
}
void TripWireTile::neighborChanged(Level *level, int x, int y, int z, int type)
{
int data = level->getData(x, y, z);
bool wasSuspended = (data & MASK_SUSPENDED) == MASK_SUSPENDED;
bool isSuspended = !level->isTopSolidBlocking(x, y - 1, z);
if (wasSuspended != isSuspended)
{
spawnResources(level, x, y, z, data, 0);
level->setTile(x, y, z, 0);
}
}
void TripWireTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, std::shared_ptr<TileEntity> forceEntity)
{
int data = level->getData(x, y, z);
bool attached = (data & MASK_ATTACHED) == MASK_ATTACHED;
bool suspended = (data & MASK_SUSPENDED) == MASK_SUSPENDED;
if (!suspended)
{
setShape(0, 0, 0, 1, 1.5f / 16.0f, 1);
}
else if (!attached)
{
setShape(0, 0, 0, 1, 8.0f / 16.0f, 1);
}
else
{
setShape(0, 1.0f / 16.0f, 0, 1, 2.5f / 16.0f, 1);
}
}
void TripWireTile::onPlace(Level *level, int x, int y, int z)
{
int data = level->isTopSolidBlocking(x, y - 1, z) ? 0 : MASK_SUSPENDED;
level->setData(x, y, z, data);
updateSource(level, x, y, z, data);
}
void TripWireTile::onRemove(Level *level, int x, int y, int z, int id, int data)
{
updateSource(level, x, y, z, data | MASK_POWERED);
}
void TripWireTile::playerWillDestroy(Level *level, int x, int y, int z, int data, std::shared_ptr<Player> player)
{
if (level->isClientSide) return;
if (player->getSelectedItem() != NULL && player->getSelectedItem()->id == Item::shears_Id)
{
level->setData(x, y, z, data | MASK_DISARMED);
}
}
void TripWireTile::updateSource(Level *level, int x, int y, int z, int data)
{
for (int dir = 0; dir < 2; dir++)
{
for (int i = 1; i < TripWireSourceTile::WIRE_DIST_MAX; i++)
{
int xx = x + Direction::STEP_X[dir] * i;
int zz = z + Direction::STEP_Z[dir] * i;
int tile = level->getTile(xx, y, zz);
if (tile == Tile::tripWireSource_Id)
{
int sourceDir = level->getData(xx, y, zz) & TripWireSourceTile::MASK_DIR;
if (sourceDir == Direction::DIRECTION_OPPOSITE[dir])
{
Tile::tripWireSource->calculateState(level, xx, y, zz, tile, level->getData(xx, y, zz), true, i, data);
}
break;
}
else if (tile != Tile::tripWire_Id)
{
break;
}
}
}
}
void TripWireTile::entityInside(Level *level, int x, int y, int z, std::shared_ptr<Entity> entity)
{
if (level->isClientSide) return;
if ((level->getData(x, y, z) & MASK_POWERED) == MASK_POWERED) return;
checkPressed(level, x, y, z);
}
void TripWireTile::tick(Level *level, int x, int y, int z, Random *random)
{
if (level->isClientSide) return;
if ((level->getData(x, y, z) & MASK_POWERED) != MASK_POWERED) return;
checkPressed(level, x, y, z);
}
void TripWireTile::checkPressed(Level *level, int x, int y, int z)
{
int data = level->getData(x, y, z);
bool wasPressed = (data & MASK_POWERED) == MASK_POWERED;
bool shouldBePressed = false;
ThreadStorage *tls = (ThreadStorage *)TlsGetValue(Tile::tlsIdxShape);
std::vector<std::shared_ptr<Entity> > *entities = level->getEntities(nullptr, AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1));
if (!entities->empty())
{
shouldBePressed = true;
}
if (shouldBePressed && !wasPressed)
{
data |= MASK_POWERED;
}
if (!shouldBePressed && wasPressed)
{
data &= ~MASK_POWERED;
}
if (shouldBePressed != wasPressed)
{
level->setData(x, y, z, data);
updateSource(level, x, y, z, data);
}
if (shouldBePressed)
{
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
}
}
bool TripWireTile::shouldConnectTo(LevelSource *level, int x, int y, int z, int data, int dir)
{
int tx = x + Direction::STEP_X[dir];
int ty = y;
int tz = z + Direction::STEP_Z[dir];
int t = level->getTile(tx, ty, tz);
bool suspended = (data & MASK_SUSPENDED) == MASK_SUSPENDED;
if (t == Tile::tripWireSource_Id)
{
int otherData = level->getData(tx, ty, tz);
int facing = otherData & TripWireSourceTile::MASK_DIR;
return facing == Direction::DIRECTION_OPPOSITE[dir];
}
if (t == Tile::tripWire_Id)
{
int otherData = level->getData(tx, ty, tz);
bool otherSuspended = (otherData & MASK_SUSPENDED) == MASK_SUSPENDED;
return suspended == otherSuspended;
}
return false;
}