Files
mcpe/source/world/level/levelgen/feature/OreFeature.cpp
2023-08-05 15:34:07 +03:00

76 lines
2.3 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 "Feature.hpp"
#include "world/level/Level.hpp"
OreFeature::OreFeature(int id, int count)
{
m_ID = id;
m_count = count;
}
bool OreFeature::place(Level* level, Random* random, int x, int y, int z)
{
float fAng = random->nextFloat() * float(M_PI);
float d0 = float(x + 8) + 0.125f * float(m_count) * Mth::sin(fAng);
float d1 = float(x + 8) - 0.125f * float(m_count) * Mth::sin(fAng);
float d2 = float(z + 8) - 0.125f * float(m_count) * Mth::cos(fAng);
float d3 = float(z + 8) - 0.125f * float(m_count) * Mth::cos(fAng);
float d4 = float(random->nextInt(3) + y + 2);
float d5 = float(random->nextInt(3) + y + 2);
// @NOTE: 1 extra block
for (int i = 0; i <= m_count; i++)
{
float d6 = d0 + ((d1 - d0) * float(i)) / float(m_count);
float d7 = d4 + ((d5 - d4) * float(i)) / float(m_count);
float d8 = d2 + ((d3 - d2) * float(i)) / float(m_count);
float d9 = (random->nextFloat() * float(m_count)) / 16.0f;
// @NOTE: seems to be calculated twice??
float radius_1 = (Mth::sin((float(M_PI * i)) / float(m_count)) + 1.0f) * d9 + 1.0f;
float radius_2 = (Mth::sin((float(M_PI * i)) / float(m_count)) + 1.0f) * d9 + 1.0f;
int minX = int(d6 - radius_1 / 2.0f);
int minY = int(d7 - radius_2 / 2.0f);
int minZ = int(d8 - radius_1 / 2.0f);
int maxX = int(d6 + radius_1 / 2.0f);
int maxY = int(d7 + radius_2 / 2.0f);
int maxZ = int(d8 + radius_1 / 2.0f);
for (int cx = minX; cx <= maxX; cx++)
{
float distX = ((float(cx) + 0.5f) - d6) / (radius_1 / 2.0f);
if (distX * distX >= 1.0f)
continue;
for (int cy = minY; cy <= maxY; cy++)
{
float distY = ((float(cy) + 0.5f) - d7) / (radius_2 / 2.0f);
if (distX * distX + distY * distY >= 1.0f)
continue;
for (int cz = minZ; cz <= maxZ; cz++)
{
float distZ = ((float(cz) + 0.5f) - d8) / (radius_1 / 2.0f);
if (distX * distX + distY * distY + distZ * distZ >= 1.0f)
continue;
if (level->getTile(cx, cy, cz) == Tile::rock->m_ID)
level->setTileNoUpdate(cx, cy, cz, m_ID);
}
}
}
}
return true;
}