Files
mcpe/source/world/level/Region.cpp
2023-11-04 13:12:35 +02:00

151 lines
3.1 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 "Region.hpp"
TileID Region::getTile(int x, int y, int z)
{
if (y < C_MIN_Y || y >= C_MAX_Y)
return TILE_AIR;
LevelChunk* pChunk = getChunkAt(x, z);
if (pChunk == nullptr)
return TILE_AIR;
return pChunk->getTile(x & 0xF, y, z & 0xF);
}
int Region::getRawBrightness(int x, int y, int z, bool b)
{
if (x < C_MIN_X || z < C_MIN_X || x >= C_MAX_X || z > C_MAX_Z)
return 15;
if (b)
{
TileID tile = getTile(x, y, z);
if (tile == Tile::stoneSlabHalf->m_ID || tile == Tile::farmland->m_ID)
{
int result;
int b1 = getRawBrightness(x, y + 1, z, false);
int b2 = getRawBrightness(x - 1, y, z, false);
int b3 = getRawBrightness(x + 1, y, z, false);
int b4 = getRawBrightness(x, y, z - 1, false);
int b5 = getRawBrightness(x, y, z + 1, false);
result = b1;
if (result < b2) result = b2;
if (result < b3) result = b3;
if (result < b4) result = b4;
if (result < b5) result = b5;
return result;
}
}
if (y < C_MIN_Y)
{
return 0;
}
if (y >= C_MAX_Y)
{
int bright = 15 - m_pLevel->m_skyDarken;
if (bright < 0)
bright = 0;
return bright;
}
//@BUG: Unsanitized input
int xd = (x >> 4) - field_4;
int zd = (z >> 4) - field_8;
return field_C[zd * field_14 + xd]->getRawBrightness(x & 0xF, y, z & 0xF, m_pLevel->m_skyDarken);
}
int Region::getRawBrightness(int x, int y, int z)
{
return getRawBrightness(x, y, z, true);
}
float Region::getBrightness(int x, int y, int z)
{
return m_pLevel->m_pDimension->field_10[getRawBrightness(x, y, z)];
}
int Region::getData(int x, int y, int z)
{
if (y < C_MIN_Y || y >= C_MAX_Y)
return 0;
int xd = (x >> 4) - field_4;
int zd = (z >> 4) - field_8;
return field_C[zd * field_14 + xd]->getData(x & 0xF, y, z & 0xF);
}
Material* Region::getMaterial(int x, int y, int z)
{
TileID tile = getTile(x, y, z);
if (tile == TILE_AIR)
return Material::air;
return Tile::tiles[tile]->m_pMaterial;
}
bool Region::isSolidTile(int x, int y, int z)
{
Tile* pTile = Tile::tiles[getTile(x, y, z)];
if (!pTile)
return false;
return pTile->isSolidRender();
}
Region::~Region()
{
delete[] field_C;
}
Region::Region(Level* level, int x1, int y1, int z1, int x2, int y2, int z2)
{
m_pLevel = level;
field_4 = x1 >> 4;
field_8 = z1 >> 4;
field_14 = 1 + (x2 >> 4) - (x1 >> 4);
field_18 = 1 + (z2 >> 4) - (z1 >> 4);
#ifndef ORIGINAL_CODE
field_C = nullptr;
assert(field_14 > 0);
assert(field_18 > 0);
if (field_14 <= 0 || field_18 <= 0)
return;
#endif
/*
field_C = new LevelChunk ** [field_14];
for (int i = 0; i < field_14; i++)
{
field_C[i] = new LevelChunk * [field_18];
}
*/
field_C = new LevelChunk * [field_14 * field_18];
for (int x = field_4; x <= x2 >> 4; x++)
{
for (int z = field_8; z <= z2 >> 4; z++)
{
field_C[(z - field_8) * field_14 + (x - field_4)] = level->getChunk(x, z);
}
}
}