mirror of
https://github.com/celisej567/mcpe.git
synced 2026-01-03 05:49:04 +03:00
109 lines
2.5 KiB
C++
109 lines
2.5 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"
|
|
|
|
bool TreeFeature::place(Level* level, Random* random, int x, int y, int z)
|
|
{
|
|
if (y <= C_MIN_Y)
|
|
return false;
|
|
|
|
int treeHeight = int(random->nextInt(3) + 4); // Between 4 and 6 blocks tall.
|
|
|
|
if (y + treeHeight >= C_MAX_Y)
|
|
return false;
|
|
|
|
// Ensure that we can place this tree
|
|
bool bCanPlace = true;
|
|
for (int ay = y; ay <= y + treeHeight; ay++)
|
|
{
|
|
int x1 = 1;
|
|
if (y + treeHeight - 1 <= ay)
|
|
x1 = 2;
|
|
else if (ay == y)
|
|
x1 = 0;
|
|
|
|
for (int ax = x - x1; ax <= x + x1 && bCanPlace; ax++)
|
|
{
|
|
for (int az = z - x1; az <= z + x1 && bCanPlace; az++)
|
|
{
|
|
if (ay < C_MIN_Y || ay >= C_MAX_Y)
|
|
{
|
|
bCanPlace = false;
|
|
break;
|
|
}
|
|
|
|
TileID tile = level->getTile(ax, ay, az);
|
|
|
|
// other trees can overlap with this one, apparently
|
|
if (tile != TILE_AIR && tile != Tile::leaves->m_ID)
|
|
{
|
|
bCanPlace = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If not, let our caller know.
|
|
if (!bCanPlace)
|
|
return false;
|
|
|
|
TileID tileBelow = level->getTile(x, y - 1, z);
|
|
|
|
// If grass or dirt aren't below us, we can't possibly grow!
|
|
if (tileBelow != Tile::grass->m_ID && tileBelow != Tile::dirt->m_ID)
|
|
return false;
|
|
|
|
// @NOTE: Redundant check
|
|
if (y >= C_MAX_Y - treeHeight)
|
|
return false;
|
|
|
|
level->setTileNoUpdate(x, y - 1, z, Tile::dirt->m_ID);
|
|
|
|
int upperY = y + treeHeight;
|
|
int lowerY = y + treeHeight - 3;
|
|
int diff = lowerY - upperY;
|
|
|
|
for (int i = lowerY; i <= upperY; i++, diff = i - upperY)
|
|
{
|
|
int c1 = 1 - diff / 2;
|
|
//int c2 = diff / 2 - 1;
|
|
for (int ax = x - c1; ax <= x + c1; ax++)
|
|
{
|
|
//int c3 = c2;
|
|
int c4 = diff / 2 - 1;
|
|
//if (c2 < 0)
|
|
// c3 = -c2;
|
|
|
|
//int c5 = c3;
|
|
|
|
for (int az = z - c1; az <= z + c1; az++, c4++)
|
|
{
|
|
if ((abs(ax - x) != c1 || abs(az - z) != c1 || (random->nextInt(2) != 0 && diff != 0)) && !Tile::solid[level->getTile(ax, i, az)])
|
|
{
|
|
level->setTileNoUpdate(ax, i, az, Tile::leaves->m_ID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < treeHeight; i++)
|
|
{
|
|
//int y1 = i + y;
|
|
TileID tile = level->getTile(x, y + i, z);
|
|
if (tile && tile != Tile::leaves->m_ID)
|
|
continue;
|
|
|
|
level->setTileNoUpdate(x, y + i, z, Tile::treeTrunk->m_ID);
|
|
}
|
|
|
|
return true;
|
|
}
|