Files
mcpe/source/world/tile/Tile.cpp

1131 lines
27 KiB
C++

/********************************************************************
Minecraft: Pocket Edition - Decompilation Project
Copyright (C) 2023 iProgramInCpp
The following code is licensed under the BSD 1 clause license.
SPDX-License-Identifier: BSD-1-Clause
********************************************************************/
#include "world/level/Level.hpp"
#include "world/item/TileItem.hpp"
#include "world/entity/ItemEntity.hpp"
// Include tile definitions here
#include "SandStoneTile.hpp"
#include "SandTile.hpp"
#include "SandStoneTile.hpp"
#include "HalfTransparentTile.hpp"
#include "GlassTile.hpp"
#include "GravelTile.hpp"
#include "StoneTile.hpp"
#include "DirtTile.hpp"
#include "GrassTile.hpp"
#include "IceTile.hpp"
#include "ClayTile.hpp"
#include "FarmTile.hpp"
#include "StoneSlabTile.hpp"
#include "ClothTile.hpp"
#include "Bush.hpp"
#include "Sapling.hpp"
#include "TopSnowTile.hpp"
#include "TreeTile.hpp"
#include "TransparentTile.hpp"
#include "LeafTile.hpp"
#include "OreTile.hpp"
#include "RedStoneOreTile.hpp"
#include "ReedTile.hpp"
#include "InvisibleTile.hpp"
#include "LiquidTileDynamic.hpp"
#include "LiquidTileStatic.hpp"
#include "ObsidianTile.hpp"
#include "MetalTile.hpp"
#include "StairTile.hpp"
#include "TorchTile.hpp"
#include "FireTile.hpp"
#include "LadderTile.hpp"
#include "TntTile.hpp"
#include "DoorTile.hpp"
#include "SpongeTile.hpp"
#include "BookshelfTile.hpp"
#include "WireTile.hpp"
std::string Tile::TILE_DESCRIPTION_PREFIX = "tile.";
Tile* Tile::tiles [C_MAX_TILES];
int Tile::lightBlock [C_MAX_TILES];
int Tile::lightEmission[C_MAX_TILES];
bool Tile::shouldTick [C_MAX_TILES];
bool Tile::solid [C_MAX_TILES];
bool Tile::translucent [C_MAX_TILES];
bool Tile::isEntityTile [C_MAX_TILES];
void Tile::_init()
{
m_TextureFrame = 1;
m_pSound = nullptr;
field_28 = 1.0f;
m_acceleration = 0.6f;
m_hardness = 0.0f;
m_blastResistance = 0.0f;
m_descriptionID = "";
}
void Tile::_init(int ID, Material* pMaterial, int texture)
{
_init();
m_ID = ID;
m_TextureFrame = texture;
m_pMaterial = pMaterial;
m_pSound = &SOUND_NORMAL;
m_aabb = m_aabbReturned = AABB(0, 0, 0, 1, 1, 1);
if (tiles[m_ID])
// @BUG: Printing &tiles[m_ID], but probably supposed to print tiles[m_ID]
LOG_W("Slot %d is already occupied by %p when adding %p", m_ID, &tiles[m_ID], this);
}
Tile::~Tile()
{
}
bool Tile::isCubeShaped()
{
return true;
}
std::string Tile::getDescriptionId()
{
return m_descriptionID;
}
std::string Tile::getName()
{
return getDescriptionId();
}
Tile* Tile::setSoundType(const Tile::SoundType& st)
{
m_pSound = &st;
return this;
}
Tile* Tile::setDescriptionId(const std::string& x)
{
m_descriptionID = TILE_DESCRIPTION_PREFIX + x;
return this;
}
Tile* Tile::setDestroyTime(float time)
{
m_hardness = time;
if (m_blastResistance < 5 * time)
m_blastResistance = 5 * time;
return this;
}
Tile* Tile::setExplodeable(float power)
{
m_blastResistance = power;
return this;
}
Tile* Tile::setLightBlock(int x)
{
lightBlock[m_ID] = x;
return this;
}
Tile* Tile::setLightEmission(float x)
{
lightEmission[m_ID] = int(15 * x);
return this;
}
Tile* Tile::setTicking(bool bTick)
{
shouldTick[m_ID] = bTick;
return this;
}
Tile* Tile::setShape(float a, float b, float c, float d, float e, float f)
{
m_aabb = AABB(a, b, c, d, e, f);
return this;
}
Tile* Tile::init()
{
setShape(m_aabb.min.x, m_aabb.min.y, m_aabb.min.z, m_aabb.max.x, m_aabb.max.y, m_aabb.max.z);
tiles[m_ID] = this;
solid[m_ID] = isSolidRender();
lightBlock[m_ID] = isSolidRender() ? 255 : 0;
translucent[m_ID] = m_pMaterial->blocksLight();
isEntityTile[m_ID] = 0;
return this;
}
int Tile::getRenderShape()
{
return 0;
}
void Tile::updateDefaultShape()
{
}
int Tile::getTexture(int x)
{
return m_TextureFrame;
}
int Tile::getTexture(int x, int y)
{
return getTexture(x);
}
int Tile::getTickDelay()
{
return 10;
}
bool Tile::isSignalSource()
{
return false;
}
int Tile::getRenderLayer()
{
return LAYER_OPAQUE;
}
bool Tile::isSolidRender()
{
return true;
}
bool Tile::mayPick()
{
return true;
}
bool Tile::mayPick(int x, bool y)
{
return mayPick();
}
int Tile::getResource(int x, Random* pRandom)
{
return m_ID;
}
int Tile::getResourceCount(Random* pRandom)
{
return 1;
}
int Tile::getSpawnResourcesAuxValue(int x)
{
return 1;
}
void Tile::initTiles()
{
Tile::sand = (new SandTile(TILE_SAND, TEXTURE_SAND, Material::sand))
->init()
->setDestroyTime(0.5f)
->setSoundType(Tile::SOUND_SAND)
->setDescriptionId("sand");
Tile::sandStone = (new SandStoneTile(TILE_SANDSTONE, TEXTURE_SANDSTONE_SIDE, Material::stone))
->init()
->setSoundType(Tile::SOUND_STONE)
->setDestroyTime(0.8f)
->setDescriptionId("sandStone");
Tile::stoneBrick = (new Tile(TILE_STONEBRICK, TEXTURE_STONEBRICK, Material::stone))
->init()
->setDestroyTime(2.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("stonebrick");
Tile::redBrick = (new Tile(TILE_BRICKS, TEXTURE_BRICKS, Material::stone))
->init()
->setDestroyTime(2.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("brick");
Tile::wood = (new Tile(TILE_WOOD, TEXTURE_PLANKS, Material::stone))
->init()
->setDestroyTime(2.0f)
->setExplodeable(5.0f)
->setSoundType(Tile::SOUND_WOOD)
->setDescriptionId("wood");
Tile::glass = (new GlassTile(TILE_GLASS, TEXTURE_GLASS, Material::glass))
->init()
->setDestroyTime(0.3f)
->setSoundType(Tile::SOUND_GLASS)
->setDescriptionId("glass");
Tile::calmWater = (new LiquidTileStatic(TILE_WATER_CALM, Material::water))
->init()
->setDestroyTime(100.0f)
->setLightBlock(3)
->setDescriptionId("water");
Tile::calmLava = (new LiquidTileStatic(TILE_LAVA_CALM, Material::lava))
->init()
->setDestroyTime(100.0f)
->setLightEmission(1.0f)
->setLightBlock(255)
->setDescriptionId("lava");
Tile::gravel = (new GravelTile(TILE_GRAVEL, TEXTURE_GRAVEL, Material::sand))
->init()
->setDestroyTime(0.6f)
->setSoundType(Tile::SOUND_GRAVEL)
->setDescriptionId("gravel");
Tile::rock = (new StoneTile(TILE_STONE, TEXTURE_STONE, Material::stone))
->init()
->setDestroyTime(1.5f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("stone");
Tile::unbreakable = (new Tile(TILE_BEDROCK, TEXTURE_BEDROCK, Material::stone))
->init()
->setDestroyTime(-1.0f)
->setExplodeable(6000000.f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("bedrock");
Tile::dirt = (new DirtTile(TILE_DIRT, TEXTURE_DIRT, Material::dirt))
->init()
->setDestroyTime(0.5f)
->setSoundType(Tile::SOUND_GRAVEL)
->setDescriptionId("dirt");
Tile::grass = (new GrassTile(TILE_GRASS, Material::dirt))
->init()
->setDestroyTime(0.6f)
->setSoundType(Tile::SOUND_GRASS)
->setDescriptionId("grass");
Tile::ice = (new IceTile(TILE_ICE, TEXTURE_ICE, Material::ice))
->init()
->setDestroyTime(0.5f)
->setLightBlock(3)
->setSoundType(Tile::SOUND_GLASS)
->setDescriptionId("ice");
Tile::clay = (new ClayTile(TILE_CLAY, TEXTURE_CLAY, Material::clay))
->init()
->setDestroyTime(0.6f)
->setSoundType(Tile::SOUND_GRAVEL)
->setDescriptionId("clay");
Tile::farmland = (new FarmTile(TILE_FARMLAND, Material::dirt))
->init()
->setDestroyTime(0.6f)
->setSoundType(Tile::SOUND_GRAVEL)
->setDescriptionId("farmland");
Tile::stoneSlab = (new StoneSlabTile(TILE_STONESLAB_FULL, true))
->init()
->setDestroyTime(2.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("stoneSlab");
Tile::stoneSlabHalf = (new StoneSlabTile(TILE_STONESLAB_HALF, false))
->init()
->setDestroyTime(2.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("stoneSlab");
Tile::cloth = (new ClothTile(TILE_CLOTH, 0xCF))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::flower = (new Bush(TILE_FLOWER, TEXTURE_FLOWER))
->init()
->setDestroyTime(0.0f)
->setSoundType(Tile::SOUND_GRASS)
->setDescriptionId("flower");
Tile::rose = (new Bush(TILE_ROSE, TEXTURE_ROSE))
->init()
->setDestroyTime(0.0f)
->setSoundType(Tile::SOUND_GRASS)
->setDescriptionId("rose");
Tile::mushroom1 = (new Bush(TILE_MUSHROOM_1, TEXTURE_MUSHROOM_BROWN))
->init()
->setDestroyTime(0.0f)
->setSoundType(Tile::SOUND_GRASS)
->setLightEmission(0.125f)
->setDescriptionId("mushroom");
Tile::mushroom2 = (new Bush(TILE_MUSHROOM_2, TEXTURE_MUSHROOM_RED))
->init()
->setDestroyTime(0.0f)
->setSoundType(Tile::SOUND_GRASS)
->setDescriptionId("mushroom");
Tile::topSnow = (new TopSnowTile(TILE_TOPSNOW, TEXTURE_SNOW, Material::snow))
->init()
->setDestroyTime(0.1f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("snow");
Tile::treeTrunk = (new TreeTile(TILE_TREE_TRUNK))
->init()
->setDestroyTime(2.0f)
->setSoundType(Tile::SOUND_WOOD)
->setDescriptionId("log");
Tile::leaves = (new LeafTile(TILE_LEAVES))
->init()
->setDestroyTime(0.2f)
->setLightBlock(true)
->setSoundType(Tile::SOUND_GRASS)
->setDescriptionId("leaves");
Tile::emeraldOre = (new OreTile(TILE_ORE_EMERALD, TEXTURE_ORE_EMERALD))
->init()
->setDestroyTime(3.0f)
->setExplodeable(5.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("oreDiamond");
Tile::redStoneOre = (new RedStoneOreTile(TILE_ORE_REDSTONE, TEXTURE_ORE_RED_STONE, false))
->init()
->setDestroyTime(3.0f)
->setExplodeable(5.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("oreRedstone");
Tile::redStoneOre_lit = (new RedStoneOreTile(TILE_ORE_REDSTONE_LIT, TEXTURE_ORE_RED_STONE, true))
->init()
->setDestroyTime(3.0f)
->setLightEmission(0.625f)
->setExplodeable(5.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("oreRedstone");
Tile::goldOre = (new OreTile(TILE_ORE_GOLD, TEXTURE_ORE_GOLD))
->init()
->setDestroyTime(3.0f)
->setExplodeable(5.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("oreGold");
Tile::ironOre = (new OreTile(TILE_ORE_IRON, TEXTURE_ORE_IRON))
->init()
->setDestroyTime(3.0f)
->setExplodeable(5.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("oreIron");
Tile::coalOre = (new OreTile(TILE_ORE_COAL, TEXTURE_ORE_COAL))
->init()
->setDestroyTime(3.0f)
->setExplodeable(5.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("oreCoal");
Tile::lapisOre = (new OreTile(TILE_ORE_LAPIS, TEXTURE_ORE_LAPIS))
->init()
->setDestroyTime(3.0f)
->setExplodeable(5.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("oreLapis");
Tile::reeds = (new ReedTile(TILE_REEDS))
->init()
->setDestroyTime(0.0f)
->setSoundType(Tile::SOUND_GRASS)
->setDescriptionId("reeds");
Tile::ladder = (new LadderTile(TILE_LADDER, TEXTURE_LADDER))
->init()
->setDestroyTime(0.4f)
->setSoundType(Tile::SOUND_WOOD)
->setDescriptionId("ladder");
Tile::obsidian = (new ObsidianTile(TILE_OBSIDIAN, TEXTURE_OBSIDIAN, Material::stone))
->init()
->setDestroyTime(10.0f)
->setExplodeable(2000.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("obsidian");
Tile::tnt = (new TntTile(TILE_TNT, TEXTURE_TNT_SIDE))
->init()
->setDestroyTime(0.0f)
->setSoundType(Tile::SOUND_GRASS)
->setDescriptionId("tnt");
Tile::torch = (new TorchTile(TILE_TORCH, TEXTURE_TORCH_LIT, Material::decoration))
->init()
->setDestroyTime(0.0f)
->setLightEmission(15.0f / 16.0f)
->setSoundType(Tile::SOUND_WOOD)
->setDescriptionId("torch");
Tile::water = (new LiquidTileDynamic(TILE_WATER, Material::water))
->init()
->setDestroyTime(100.0f)
->setLightBlock(3)
->setDescriptionId("water");
Tile::lava = (new LiquidTileDynamic(TILE_LAVA, Material::lava))
->init()
->setDestroyTime(0.0f)
->setLightEmission(1.0f)
->setLightBlock(255)
->setDescriptionId("lava");
Tile::fire = (new FireTile(TILE_FIRE, TEXTURE_FIRE1))
->init()
->setDestroyTime(0.0f)
->setLightEmission(1.0f)
->setSoundType(Tile::SOUND_WOOD) // @NOTE: Setting fire's sound to Wood
->setDescriptionId("fire");
Tile::invisible_bedrock = (new InvisibleTile(TILE_INVISIBLE, TEXTURE_STONE, Material::stone))
->init()
->setDestroyTime(-1.0f)
->setExplodeable(6000000.0f);
Tile::goldBlock = (new MetalTile(TILE_BLOCK_GOLD, TEXTURE_GOLD, Material::metal))
->init()
->setDestroyTime(3.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_METAL)
->setDescriptionId("blockGold");
Tile::ironBlock = (new MetalTile(TILE_BLOCK_IRON, TEXTURE_IRON, Material::metal))
->init()
->setDestroyTime(5.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_METAL)
->setDescriptionId("blockIron");
Tile::emeraldBlock = (new MetalTile(TILE_BLOCK_EMERALD, TEXTURE_EMERALD, Material::metal))
->init()
->setDestroyTime(5.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_METAL)
->setDescriptionId("blockEmerald");
Tile::stairs_wood = (new StairTile(TILE_STAIRS_WOOD, Tile::wood))
->init()
->setDescriptionId("stairsWood");
Tile::stairs_stone = (new StairTile(TILE_STAIRS_STONE, Tile::stoneBrick))
->init()
->setDescriptionId("stairsStone");
Tile::door_wood = (new DoorTile(TILE_DOOR_WOOD, Material::wood))
->init()
->setDestroyTime(3.0f)
->setSoundType(Tile::SOUND_WOOD)
->setDescriptionId("doorWood");
Tile::door_iron = (new DoorTile(TILE_DOOR_IRON, Material::metal))
->init()
->setDestroyTime(5.0f)
->setSoundType(Tile::SOUND_METAL)
->setDescriptionId("doorIron");
Tile::cloth_00 = (new ClothTile(TILE_CLOTH_00, 15))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_10 = (new ClothTile(TILE_CLOTH_10, 14))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_20 = (new ClothTile(TILE_CLOTH_20, 13))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_30 = (new ClothTile(TILE_CLOTH_30, 12))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_40 = (new ClothTile(TILE_CLOTH_40, 11))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_50 = (new ClothTile(TILE_CLOTH_50, 10))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_60 = (new ClothTile(TILE_CLOTH_60, 9))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_70 = (new ClothTile(TILE_CLOTH_70, 8))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_01 = (new ClothTile(TILE_CLOTH_01, 7))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_11 = (new ClothTile(TILE_CLOTH_11, 6))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_21 = (new ClothTile(TILE_CLOTH_21, 5))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_31 = (new ClothTile(TILE_CLOTH_31, 4))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_41 = (new ClothTile(TILE_CLOTH_41, 3))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_51 = (new ClothTile(TILE_CLOTH_51, 2))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::cloth_61 = (new ClothTile(TILE_CLOTH_61, 1))
->init()
->setDestroyTime(0.8f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("cloth");
Tile::info_updateGame1 = (new DirtTile(TILE_UPDATE, TEXTURE_UPDATE, Material::dirt))
->init()
->setDestroyTime(5.0f)
->setSoundType(Tile::SOUND_GRAVEL)
->setDescriptionId("info_update");
Tile::info_updateGame2 = (new DirtTile(TILE_ATEUPD, TEXTURE_ATEUPD, Material::dirt))
->init()
->setDestroyTime(5.0f)
->setSoundType(Tile::SOUND_GRAVEL)
->setDescriptionId("info_ateupd");
// custom additions here
Tile::sapling = (new Sapling(TILE_SAPLING, TEXTURE_SAPLING))
->init()
->setDestroyTime(0.0f)
->setSoundType(Tile::SOUND_GRASS)
->setDescriptionId("sapling");
Tile::sponge = (new SpongeTile(TILE_SPONGE, TEXTURE_SPONGE))
->init()
->setDestroyTime(0.5f)
->setSoundType(Tile::SOUND_CLOTH)
->setDescriptionId("sponge");
Tile::lapisBlock = (new MetalTile(TILE_BLOCK_LAPIS, TEXTURE_LAPIS, Material::metal))
->init()
->setDestroyTime(3.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_METAL)
->setDescriptionId("blockLapis");
Tile::bookshelf = (new BookshelfTile(TILE_BOOKSHELF, TEXTURE_BOOKSHELF, Material::wood))
->init()
->setDestroyTime(1.5f)
->setSoundType(Tile::SOUND_WOOD)
->setDescriptionId("bookshelf");
Tile::mossStone = (new Tile(TILE_MOSS_STONE, TEXTURE_MOSSY_STONE, Material::stone))
->init()
->setDestroyTime(2.0f)
->setExplodeable(10.0f)
->setSoundType(Tile::SOUND_STONE)
->setDescriptionId("stoneMoss");
//Tile::cryingObsidian = (new Tile(TILE_OBSIDIAN_CRYING, TEXTURE_OBSIDIAN_CRYING, Material::stone))
// ->init()
// ->setDestroyTime(10.0f)
// ->setExplodeable(2000.0f)
// ->setSoundType(Tile::SOUND_STONE)
// ->setDescriptionId("cryingObsidian");
for (int i = 0; i < C_MAX_TILES; i++)
{
if (Tile::tiles[i])
Item::items[i] = new TileItem(i - C_MAX_TILES);
}
}
void Tile::teardownTiles()
{
for (int i = 0; i < C_MAX_TILES; i++)
delete tiles[i];
}
void Tile::updateShape(LevelSource* a, int x, int y, int z)
{
}
void Tile::addLights(Level* p, int x, int y, int z)
{
}
float Tile::getBrightness(LevelSource* pSrc, int x, int y, int z)
{
return pSrc->getBrightness(x, y, z);
}
int Tile::getColor(LevelSource* pSrc, int x, int y, int z)
{
return 0xFFFFFF; // White
}
AABB* Tile::getAABB(Level* pLevel, int x, int y, int z)
{
Vec3 offset((float)x, (float)y, (float)z);
m_aabbReturned = AABB(offset + m_aabb.min, offset + m_aabb.max);
return &m_aabbReturned;
}
AABB Tile::getTileAABB(Level* pLevel, int x, int y, int z)
{
Vec3 offset((float)x, (float)y, (float)z);
return AABB(offset + m_aabb.min, offset + m_aabb.max);
}
void Tile::addAABBs(Level* pLevel, int x, int y, int z, const AABB* aabb, std::vector<AABB>& out)
{
AABB* pTileAABB = getAABB(pLevel, x, y, z);
if (pTileAABB && pTileAABB->intersect(*aabb))
{
out.push_back(*pTileAABB);
}
}
bool Tile::shouldRenderFace(LevelSource* pSrc, int x, int y, int z, int dir)
{
if (z == -1 && dir == DIR_ZNEG) return false;
if (z == C_MAX_CHUNKS_Z * 16 && dir == DIR_ZPOS) return false;
if (x == -1 && dir == DIR_XNEG) return false;
if (x == C_MAX_CHUNKS_X * 16 && dir == DIR_XPOS) return false;
if (y == -1 && dir == DIR_YNEG) return false;
if (dir == DIR_YNEG && m_aabb.min.y > 0.0f) return true;
if (dir == DIR_YPOS && m_aabb.max.y < 1.0f) return true;
if (dir == DIR_ZNEG && m_aabb.min.z > 0.0f) return true;
if (dir == DIR_ZPOS && m_aabb.max.z < 1.0f) return true;
if (dir == DIR_XNEG && m_aabb.min.x > 0.0f) return true;
if (dir == DIR_XPOS && m_aabb.max.x < 1.0f) return true;
Tile* pTile = Tile::tiles[pSrc->getTile(x, y, z)];
if (!pTile)
return true;
if (dir == DIR_YPOS && pTile->m_ID == Tile::topSnow->m_ID)
return false;
return !pTile->isSolidRender();
}
int Tile::getTexture(LevelSource* pSrc, int x, int y, int z, int dir)
{
return getTexture(dir, pSrc->getData(x, y, z));
}
bool Tile::canSurvive(Level* pLevel, int x, int y, int z)
{
return true;
}
// returns if we can place over the tile
bool Tile::mayPlace(Level* pLevel, int x, int y, int z)
{
TileID tile = pLevel->getTile(x, y, z);
if (!tile)
return true; // we can definitely place something over air
return Tile::tiles[tile]->m_pMaterial->isLiquid();
}
void Tile::tick(Level* pLevel, int x, int y, int z, Random* pRandom)
{
}
void Tile::animateTick(Level* pLevel, int x, int y, int z, Random* pRandom)
{
}
void Tile::destroy(Level* pLevel, int x, int y, int z, int dir)
{
}
void Tile::neighborChanged(Level* pLevel, int x, int y, int z, int dir)
{
}
void Tile::onPlace(Level* pLevel, int x, int y, int z)
{
}
void Tile::onRemove(Level* pLevel, int x, int y, int z)
{
}
bool Tile::containsX(const Vec3& v)
{
return v.y >= m_aabb.min.y
&& v.y <= m_aabb.max.y
&& v.z >= m_aabb.min.z
&& v.z <= m_aabb.max.z;
}
bool Tile::containsY(const Vec3& v)
{
return v.x >= m_aabb.min.x
&& v.x <= m_aabb.max.x
&& v.z >= m_aabb.min.z
&& v.z <= m_aabb.max.z;
}
bool Tile::containsZ(const Vec3& v)
{
return v.x >= m_aabb.min.x
&& v.x <= m_aabb.max.x
&& v.y >= m_aabb.min.y
&& v.y <= m_aabb.max.y;
}
HitResult Tile::clip(Level* level, int x, int y, int z, Vec3 vec1, Vec3 vec2)
{
updateShape(level, x, y, z);
Vec3 clipMinX, clipMinY, clipMinZ;
Vec3 clipMaxX, clipMaxY, clipMaxZ;
bool bClipMinX, bClipMinY, bClipMinZ;
bool bClipMaxX, bClipMaxY, bClipMaxZ;
vec1 += Vec3(-float(x), -float(y), -float(z));
vec2 += Vec3(-float(x), -float(y), -float(z));
bClipMinX = vec1.clipX(vec2, m_aabb.min.x, clipMinX) && containsX(clipMinX);
bClipMaxX = vec1.clipX(vec2, m_aabb.max.x, clipMaxX) && containsX(clipMaxX);
bClipMinY = vec1.clipY(vec2, m_aabb.min.y, clipMinY) && containsY(clipMinY);
bClipMaxY = vec1.clipY(vec2, m_aabb.max.y, clipMaxY) && containsY(clipMaxY);
bClipMinZ = vec1.clipZ(vec2, m_aabb.min.z, clipMinZ) && containsZ(clipMinZ);
bClipMaxZ = vec1.clipZ(vec2, m_aabb.max.z, clipMaxZ) && containsZ(clipMaxZ);
// the collided side of our AABB
HitResult::eHitSide collType = HitResult::NOHIT;
// the preferred vector for our collision
Vec3* pVec = nullptr;
if (bClipMinX)
pVec = &clipMinX, collType = HitResult::MINX;
if (bClipMaxX)
{
if (!pVec || clipMaxX.distanceToSqr(vec1) < pVec->distanceToSqr(vec1))
pVec = &clipMaxX, collType = HitResult::MAXX;
}
if (bClipMinY)
{
if (!pVec || clipMinY.distanceToSqr(vec1) < pVec->distanceToSqr(vec1))
pVec = &clipMinY, collType = HitResult::MINY;
}
if (bClipMaxY)
{
if (!pVec || clipMaxY.distanceToSqr(vec1) < pVec->distanceToSqr(vec1))
pVec = &clipMaxY, collType = HitResult::MAXY;
}
if (bClipMinZ)
{
if (!pVec || clipMinZ.distanceToSqr(vec1) < pVec->distanceToSqr(vec1))
pVec = &clipMinZ, collType = HitResult::MINZ;
}
if (bClipMaxZ)
{
if (!pVec || clipMaxZ.distanceToSqr(vec1) < pVec->distanceToSqr(vec1))
pVec = &clipMaxZ, collType = HitResult::MAXZ;
}
if (!pVec)
{
// return a nothing burger
return HitResult();
}
return HitResult(x, y, z, collType, *pVec + Vec3(float(x), float(y), float(z)));
}
int Tile::getSignal(LevelSource* pLevel, int x, int y, int z)
{
return 0;
}
int Tile::getSignal(LevelSource* pLevel, int x, int y, int z, int dir)
{
return 0;
}
int Tile::getDirectSignal(Level* pLevel, int x, int y, int z, int dir)
{
return 0;
}
void Tile::triggerEvent(Level* pLevel, int x, int y, int z, int a, int b)
{
}
void Tile::entityInside(Level* pLevel, int x, int y, int z, Entity* pEnt)
{
}
void Tile::handleEntityInside(Level* pLevel, int x, int y, int z, Entity* pEnt, Vec3& vec)
{
}
float Tile::getDestroyProgress(Player* player)
{
if (m_hardness < 0.0f)
return 0.0f;
if (!player->canDestroy(this))
return (1.0f - m_hardness) / 100.0f;
return player->getDestroySpeed() / m_hardness / 30.0f;
}
void Tile::spawnResources(Level* pLevel, int x, int y, int z, int i)
{
return spawnResources(pLevel, x, y, z, i, 1.0f);
}
void Tile::spawnResources(Level* pLevel, int x, int y, int z, int data, float fChance)
{
if (pLevel->m_bIsMultiplayer)
return;
#ifdef TEST_SURVIVAL_MODE
int count = getResourceCount(&pLevel->m_random);
for (int i = 0; i < count; i++)
{
if (pLevel->m_random.nextFloat() > fChance)
continue;
int id = getResource(data, &pLevel->m_random);
if (id <= 0)
continue;
float xo = (pLevel->m_random.nextFloat() * 0.7f) + (1.0f - 0.7f) * 0.5f;
float yo = (pLevel->m_random.nextFloat() * 0.7f) + (1.0f - 0.7f) * 0.5f;
float zo = (pLevel->m_random.nextFloat() * 0.7f) + (1.0f - 0.7f) * 0.5f;
ItemInstance inst(id, 1, getSpawnResourcesAuxValue(data));
ItemEntity* pEntity = new ItemEntity(pLevel, float(x) + xo, float(y) + yo, float(z) + zo, &inst);
pEntity->field_E4 = 10;
pLevel->addEntity(pEntity);
}
#endif
}
int Tile::spawnBurnResources(Level*, float, float, float)
{
return 0;
}
float Tile::getExplosionResistance(Entity* entity)
{
return m_blastResistance / 5.0f;
}
void Tile::wasExploded(Level* pLevel, int x, int y, int z)
{
}
int Tile::use(Level* pLevel, int x, int y, int z, Player* player)
{
return 0;
}
void Tile::stepOn(Level* pLevel, int x, int y, int z, Entity* entity)
{
}
void Tile::setPlacedOnFace(Level* pLevel, int x, int y, int z, int dir)
{
}
void Tile::setPlacedBy(Level* pLevel, int x, int y, int z, Mob* mob)
{
}
void Tile::prepareRender(Level* pLevel, int x, int y, int z)
{
}
void Tile::attack(Level* pLevel, int x, int y, int z, Player* player)
{
}
void Tile::playerDestroy(Level* level, Player* player, int x, int y, int z, int i)
{
spawnResources(level, x, y, z, i);
}
Tile::SoundType
Tile::SOUND_NORMAL("stone", 1.0f, 1.0f),
Tile::SOUND_WOOD ("wood", 1.0f, 1.0f),
Tile::SOUND_GRAVEL("gravel", 1.0f, 1.0f),
Tile::SOUND_GRASS ("grass", 0.5f, 1.0f),
Tile::SOUND_STONE ("stone", 1.0f, 1.0f),
Tile::SOUND_METAL ("stone", 1.0f, 1.5f),
Tile::SOUND_GLASS ("stone", 1.0f, 1.0f),
Tile::SOUND_CLOTH ("cloth", 1.0f, 1.0f),
Tile::SOUND_SAND ("sand", 1.0f, 1.0f),
Tile::SOUND_SILENT("", 1.0f, 1.0f);
// @TODO: Refactor this so that Tile::fire is already a FireTile* etc
Tile
*Tile::sand,
*Tile::sandStone,
*Tile::stoneBrick,
*Tile::redBrick,
*Tile::wood,
*Tile::glass,
*Tile::calmWater,
*Tile::calmLava,
*Tile::gravel,
*Tile::rock,
*Tile::unbreakable,
*Tile::dirt,
*Tile::grass,
*Tile::ice,
*Tile::clay,
*Tile::farmland,
*Tile::stoneSlab,
*Tile::stoneSlabHalf,
*Tile::cloth,
*Tile::cloth_00,
*Tile::cloth_10,
*Tile::cloth_20,
*Tile::cloth_30,
*Tile::cloth_40,
*Tile::cloth_50,
*Tile::cloth_60,
*Tile::cloth_70,
*Tile::cloth_01,
*Tile::cloth_11,
*Tile::cloth_21,
*Tile::cloth_31,
*Tile::cloth_41,
*Tile::cloth_51,
*Tile::cloth_61,
*Tile::flower,
*Tile::rose,
*Tile::mushroom1,
*Tile::mushroom2,
*Tile::topSnow,
*Tile::treeTrunk,
*Tile::leaves,
*Tile::emeraldOre, //! actually diamond ore
*Tile::redStoneOre,
*Tile::redStoneOre_lit,
*Tile::goldOre,
*Tile::ironOre,
*Tile::coalOre,
*Tile::lapisOre,
*Tile::reeds,
*Tile::ladder,
*Tile::obsidian,
*Tile::tnt,
*Tile::torch,
*Tile::water,
*Tile::lava,
*Tile::fire,
*Tile::invisible_bedrock,
*Tile::goldBlock,
*Tile::ironBlock,
*Tile::emeraldBlock, //! actually diamond block
*Tile::stairs_wood,
*Tile::stairs_stone,
*Tile::door_wood,
*Tile::door_iron,
*Tile::info_updateGame1,
*Tile::info_updateGame2,
*Tile::sapling,
*Tile::sponge,
*Tile::lapisBlock,
*Tile::bookshelf,
*Tile::mossStone;
//*Tile::cryingObsidian;