4jcraft/Minecraft.World/Blocks/SkullTile.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

271 lines
8.2 KiB
C++

#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.h"
#include "../Headers/net.minecraft.world.item.h"
#include "../Headers/net.minecraft.world.level.tile.entity.h"
#include "../Headers/net.minecraft.h"
#include "SkullTile.h"
SkullTile::SkullTile(int id) : EntityTile(id, Material::decoration, false)
{
setShape(4.0f / 16.0f, 0, 4.0f / 16.0f, 12.0f / 16.0f, .5f, 12.0f / 16.0f);
}
int SkullTile::getRenderShape()
{
return SHAPE_INVISIBLE;
}
bool SkullTile::isSolidRender(bool isServerLevel)
{
return false;
}
bool SkullTile::isCubeShaped()
{
return false;
}
void SkullTile::updateShape(LevelSource *level, int x, int y, int z, int forceData , std::shared_ptr<TileEntity> forceEntity)
{
int data = level->getData(x, y, z) & PLACEMENT_MASK;
switch (data)
{
default:
case Facing::UP:
setShape(4.0f / 16.0f, 0, 4.0f / 16.0f, 12.0f / 16.0f, .5f, 12.0f / 16.0f);
break;
case Facing::NORTH:
setShape(4.0f / 16.0f, 4.0f / 16.0f, .5f, 12.0f / 16.0f, 12.0f / 16.0f, 1);
break;
case Facing::SOUTH:
setShape(4.0f / 16.0f, 4.0f / 16.0f, 0, 12.0f / 16.0f, 12.0f / 16.0f, .5f);
break;
case Facing::WEST:
setShape(.5f, 4.0f / 16.0f, 4.0f / 16.0f, 1, 12.0f / 16.0f, 12.0f / 16.0f);
break;
case Facing::EAST:
setShape(0, 4.0f / 16.0f, 4.0f / 16.0f, .5f, 12.0f / 16.0f, 12.0f / 16.0f);
break;
}
}
AABB *SkullTile::getAABB(Level *level, int x, int y, int z)
{
updateShape(level, x, y, z);
return EntityTile::getAABB(level, x, y, z);
}
void SkullTile::setPlacedBy(Level *level, int x, int y, int z, std::shared_ptr<Mob> by)
{
int dir = Mth::floor(by->yRot * 4 / (360) + 2.5) & 3;
level->setData(x, y, z, dir);
}
std::shared_ptr<TileEntity> SkullTile::newTileEntity(Level *level)
{
return std::shared_ptr<SkullTileEntity>(new SkullTileEntity());
}
int SkullTile::cloneTileId(Level *level, int x, int y, int z)
{
return Item::skull_Id;
}
int SkullTile::cloneTileData(Level *level, int x, int y, int z)
{
std::shared_ptr<TileEntity> tileEntity = level->getTileEntity(x, y, z);
std::shared_ptr<SkullTileEntity> skull = std::dynamic_pointer_cast<SkullTileEntity>(tileEntity);
if (skull != NULL)
{
return skull->getSkullType();
}
return 0;
// 4J Stu - Not added yet
//return EntityTile::cloneTileData(level, x, y, z);
}
int SkullTile::getSpawnResourcesAuxValue(int data)
{
return data;
}
void SkullTile::spawnResources(Level *level, int x, int y, int z, int data, float odds, int playerBonusLevel)
{
// do nothing, resource is popped by onRemove
// ... because the tile entity is removed prior to spawnResources
}
void SkullTile::playerWillDestroy(Level *level, int x, int y, int z, int data, std::shared_ptr<Player> player)
{
// 4J Stu - Not implemented
#if 0
if (player->abilities.instabuild)
{
// prevent resource drop
data |= NO_DROP_BIT;
level.setData(x, y, z, data);
}
EntityTile::playerWillDestroy(level, x, y, z, data, player);
#endif
}
void SkullTile::onRemove(Level *level, int x, int y, int z)//, int id, int data)
{
if (level->isClientSide) return;
int data = level->getData(x, y, z);
if ((data & NO_DROP_BIT) == 0)
{
std::shared_ptr<ItemInstance> item = std::shared_ptr<ItemInstance>(new ItemInstance(Item::skull_Id, 1, cloneTileData(level, x, y, z)));
std::shared_ptr<SkullTileEntity> entity = std::dynamic_pointer_cast<SkullTileEntity>(level->getTileEntity(x, y, z));
if (entity->getSkullType() == SkullTileEntity::TYPE_CHAR && !entity->getExtraType().empty())
{
item->setTag(new CompoundTag());
item->getTag()->putString(L"SkullOwner", entity->getExtraType());
}
popResource(level, x, y, z, item);
}
EntityTile::onRemove(level, x, y, z, id, data);
}
int SkullTile::getResource(int data, Random *random, int playerBonusLevel)
{
return Item::skull_Id;
}
void SkullTile::checkMobSpawn(Level *level, int x, int y, int z, std::shared_ptr<SkullTileEntity> placedSkull)
{
// 4J Stu - Don't have Withers yet, so don't need this
#if 0
if (placedSkull.getSkullType() == SkullTileEntity.TYPE_WITHER && y >= 2 && level.difficulty > Difficulty.PEACEFUL) {
// check wither boss spawn
final int ss = Tile.hellSand.id;
// north-south alignment
for (int zo = -2; zo <= 0; zo++) {
if ( //
level.getTile(x, y - 1, z + zo) == ss && //
level.getTile(x, y - 1, z + zo + 1) == ss && //
level.getTile(x, y - 2, z + zo + 1) == ss && //
level.getTile(x, y - 1, z + zo + 2) == ss && //
isSkullAt(level, x, y, z + zo, SkullTileEntity.TYPE_WITHER) && //
isSkullAt(level, x, y, z + zo + 1, SkullTileEntity.TYPE_WITHER) && //
isSkullAt(level, x, y, z + zo + 2, SkullTileEntity.TYPE_WITHER)) {
level.setDataNoUpdate(x, y, z + zo, NO_DROP_BIT);
level.setDataNoUpdate(x, y, z + zo + 1, NO_DROP_BIT);
level.setDataNoUpdate(x, y, z + zo + 2, NO_DROP_BIT);
level.setTileNoUpdate(x, y, z + zo, 0);
level.setTileNoUpdate(x, y, z + zo + 1, 0);
level.setTileNoUpdate(x, y, z + zo + 2, 0);
level.setTileNoUpdate(x, y - 1, z + zo, 0);
level.setTileNoUpdate(x, y - 1, z + zo + 1, 0);
level.setTileNoUpdate(x, y - 1, z + zo + 2, 0);
level.setTileNoUpdate(x, y - 2, z + zo + 1, 0);
if (!level.isClientSide) {
WitherBoss witherBoss = new WitherBoss(level);
witherBoss.moveTo(x + 0.5, y - 1.45, z + zo + 1.5, 90, 0);
witherBoss.yBodyRot = 90;
witherBoss.makeInvulnerable();
level.addEntity(witherBoss);
}
for (int i = 0; i < 120; i++) {
level.addParticle("snowballpoof", x + level.random.nextDouble(), y - 2 + level.random.nextDouble() * 3.9, z + zo + 1 + level.random.nextDouble(), 0, 0, 0);
}
level.tileUpdated(x, y, z + zo, 0);
level.tileUpdated(x, y, z + zo + 1, 0);
level.tileUpdated(x, y, z + zo + 2, 0);
level.tileUpdated(x, y - 1, z + zo, 0);
level.tileUpdated(x, y - 1, z + zo + 1, 0);
level.tileUpdated(x, y - 1, z + zo + 2, 0);
level.tileUpdated(x, y - 2, z + zo + 1, 0);
return;
}
}
// west-east alignment
for (int xo = -2; xo <= 0; xo++) {
if ( //
level.getTile(x + xo, y - 1, z) == ss && //
level.getTile(x + xo + 1, y - 1, z) == ss && //
level.getTile(x + xo + 1, y - 2, z) == ss && //
level.getTile(x + xo + 2, y - 1, z) == ss && //
isSkullAt(level, x + xo, y, z, SkullTileEntity.TYPE_WITHER) && //
isSkullAt(level, x + xo + 1, y, z, SkullTileEntity.TYPE_WITHER) && //
isSkullAt(level, x + xo + 2, y, z, SkullTileEntity.TYPE_WITHER)) {
level.setDataNoUpdate(x + xo, y, z, NO_DROP_BIT);
level.setDataNoUpdate(x + xo + 1, y, z, NO_DROP_BIT);
level.setDataNoUpdate(x + xo + 2, y, z, NO_DROP_BIT);
level.setTileNoUpdate(x + xo, y, z, 0);
level.setTileNoUpdate(x + xo + 1, y, z, 0);
level.setTileNoUpdate(x + xo + 2, y, z, 0);
level.setTileNoUpdate(x + xo, y - 1, z, 0);
level.setTileNoUpdate(x + xo + 1, y - 1, z, 0);
level.setTileNoUpdate(x + xo + 2, y - 1, z, 0);
level.setTileNoUpdate(x + xo + 1, y - 2, z, 0);
if (!level.isClientSide) {
WitherBoss witherBoss = new WitherBoss(level);
witherBoss.moveTo(x + xo + 1.5, y - 1.45, z + .5, 0, 0);
witherBoss.makeInvulnerable();
level.addEntity(witherBoss);
}
for (int i = 0; i < 120; i++) {
level.addParticle("snowballpoof", x + xo + 1 + level.random.nextDouble(), y - 2 + level.random.nextDouble() * 3.9, z + level.random.nextDouble(), 0, 0, 0);
}
level.tileUpdated(x + xo, y, z, 0);
level.tileUpdated(x + xo + 1, y, z, 0);
level.tileUpdated(x + xo + 2, y, z, 0);
level.tileUpdated(x + xo, y - 1, z, 0);
level.tileUpdated(x + xo + 1, y - 1, z, 0);
level.tileUpdated(x + xo + 2, y - 1, z, 0);
level.tileUpdated(x + xo + 1, y - 2, z, 0);
return;
}
}
}
#endif
}
bool SkullTile::isSkullAt(Level *level, int x, int y, int z, int skullType)
{
if (level->getTile(x, y, z) != id)
{
return false;
}
std::shared_ptr<TileEntity> te = level->getTileEntity(x, y, z);
std::shared_ptr<SkullTileEntity> skull = std::dynamic_pointer_cast<SkullTileEntity>(te);
if (skull == NULL)
{
return false;
}
return skull->getSkullType() == skullType;
}
void SkullTile::registerIcons(IconRegister *iconRegister)
{
// None
}
Icon *SkullTile::getTexture(int face, int data)
{
return Tile::hellSand->getTexture(face);
}
std::wstring SkullTile::getTileItemIconName()
{
return L"";
//return SkullItem::ICON_NAMES[0];
}