Files
mcpe/source/world/level/levelgen/chunk/TestChunkSource.cpp

197 lines
4.7 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 "TestChunkSource.hpp"
#include "world/level/Level.hpp"
TestChunkSource::TestChunkSource(Level* pLevel)
{
m_pLevel = pLevel;
memset(m_chunkMap, 0, sizeof m_chunkMap);
m_pEmptyChunk = new EmptyLevelChunk(pLevel, nullptr, 0, 0);
m_lastChunkX = -99999;
m_lastChunkZ = -99999;
m_pLastChunk = m_pEmptyChunk;
}
TestChunkSource::~TestChunkSource()
{
for (int z = 0; z < C_MAX_CHUNKS_Z; z++)
{
for (int x = 0; x < C_MAX_CHUNKS_X; x++)
{
if (m_chunkMap[z][x])
delete m_chunkMap[z][x];
}
}
}
LevelChunk* TestChunkSource::generateChunk(int x, int z)
{
//@NOTE: This gets called a dangerous amount of recursions (for the entire damn world!)
// We really should fix this...
if (x < 0 || z < 0 || x >= C_MAX_CHUNKS_X || z >= C_MAX_CHUNKS_Z)
return nullptr;
if (m_chunkMap[z][x])
return m_chunkMap[z][x];
TileID* pData = new TileID[0x8000u];
memset(pData, 0, 0x8000u * sizeof(TileID));
for (int i = 0; i != 66; i++)
{
for (int j = 0; j < 16; j++)
{
for (int k = 0; k < 16; k++)
{
TileID* p = &pData[i | (j << 11) | (k << 7)];
if (i == 0)
*p = TILE_BEDROCK;
//else if (j == 0 || k == 0)
// *p = TILE_AIR;
else if (i == 65) {
/*if (rand() % 10 == 0)
*p = TILE_ROSE;
else if (rand() % 10 == 0)
*p = TILE_FLOWER;
else if (rand() % 10 == 0)
*p = TILE_TOPSNOW;*/
}
else if (i > 64)
*p = TILE_AIR;
else if (i == 64) {
//if ((j + k) % 2 == 0)
*p = TILE_GRASS;
}
else if (i > 60)
*p = TILE_DIRT;
else if (i > 3)
*p = TILE_STONE;
else
*p = TILE_STONEBRICK;
// generate a hole at (128,0,128) for testing
//if (i == 0 && j == 0 && k == 0 && x == 8 && z == 8)
// *p = TILE_WOOD;
}
}
}
LevelChunk* pChunk = new LevelChunk(m_pLevel, pData, x, z);
m_chunkMap[z][x] = pChunk;
/*
// block light updates during level generation
bool bOldState = m_pLevel->m_bUpdateLights;
m_pLevel->m_bUpdateLights = false;
// encode this chunk's X/Z coordinate by setting bits in it
pChunk->setTile(0, 65, 0, TILE_WOOD);
pChunk->setTile(0, 65, 1, TILE_STONE);
pChunk->setTile(3+1, 65, 0, (x & (1 << 0)) ? TILE_STONEBRICK : TILE_BEDROCK);
pChunk->setTile(2+1, 65, 0, (x & (1 << 1)) ? TILE_STONEBRICK : TILE_BEDROCK);
pChunk->setTile(1+1, 65, 0, (x & (1 << 2)) ? TILE_STONEBRICK : TILE_BEDROCK);
pChunk->setTile(0+1, 65, 0, (x & (1 << 3)) ? TILE_STONEBRICK : TILE_BEDROCK);
pChunk->setTile(3+1, 65, 1, (z & (1 << 0)) ? TILE_STONEBRICK : TILE_BEDROCK);
pChunk->setTile(2+1, 65, 1, (z & (1 << 1)) ? TILE_STONEBRICK : TILE_BEDROCK);
pChunk->setTile(1+1, 65, 1, (z & (1 << 2)) ? TILE_STONEBRICK : TILE_BEDROCK);
pChunk->setTile(0+1, 65, 1, (z & (1 << 3)) ? TILE_STONEBRICK : TILE_BEDROCK);
m_pLevel->m_bUpdateLights = bOldState;
pChunk->setBrightness(LightLayer::Block, 0, 0, 0, 3);
pChunk->setBrightness(LightLayer::Block, 0, 1, 0, 4);
pChunk->setBrightness(LightLayer::Block, 0, 2, 0, 5);
pChunk->setBrightness(LightLayer::Block, 0, 3, 0, 6);
int br1 = pChunk->getBrightness(LightLayer::Block, 0, 0, 0);
int br2 = pChunk->getBrightness(LightLayer::Block, 0, 1, 0);
int br3 = pChunk->getBrightness(LightLayer::Block, 0, 2, 0);
int br4 = pChunk->getBrightness(LightLayer::Block, 0, 3, 0);
assert(br1 == 3);
assert(br2 == 4);
assert(br3 == 5);
assert(br4 == 6);
*/
pChunk->recalcHeightmap();
return pChunk;
}
LevelChunk* TestChunkSource::create(int x, int z)
{
if (m_lastChunkX == x && m_lastChunkZ == z)
return m_pLastChunk;
LevelChunk* pChk = generateChunk(x, z);
if (!pChk)
pChk = m_pEmptyChunk;
m_lastChunkX = x;
m_lastChunkZ = z;
m_pLastChunk = pChk;
return pChk;
}
std::string TestChunkSource::gatherStats()
{
return "TestChunkSource";
}
LevelChunk* TestChunkSource::getChunk(int x, int z)
{
return create(x, z);
}
LevelChunk* TestChunkSource::getChunkDontCreate(int x, int z)
{
if (x < 0 || z < 0 || x >= C_MAX_CHUNKS_X || z >= C_MAX_CHUNKS_Z)
return nullptr;
if (m_chunkMap[z][x])
return m_chunkMap[z][x];
TileID* pData = new TileID[0x8000u];
memset(pData, 0, 0x8000u * sizeof(TileID));
m_chunkMap[z][x] = new LevelChunk(m_pLevel, pData, x, z);
m_pLastChunk = m_chunkMap[z][x];
m_lastChunkX = x;
m_lastChunkZ = z;
return m_chunkMap[z][x];
}
bool TestChunkSource::hasChunk(int x, int z)
{
return true;
}
void TestChunkSource::postProcess(ChunkSource* a, int b, int c)
{
}
bool TestChunkSource::shouldSave()
{
return false;
}
int TestChunkSource::tick()
{
return 0;
}