Files
neoStudiosLCE-neoLegacy/Minecraft.World/IceSpikeFeature.cpp
Lord Cambion 10b7fc36d3 Biome Update!
2026-03-26 20:37:51 +01:00

111 lines
3.3 KiB
C++

#include "IceSpikeFeature.h"
#include <cmath>
#include "Level.h"
#include "Tile.h"
#include <algorithm>
IceSpikeFeature::IceSpikeFeature() {}
bool IceSpikeFeature::place(Level *level, Random *random, int x, int y, int z)
{
while (level->isEmptyTile(x, y, z) && y > 2)
{
y--;
}
if (level->getTile(x, y, z) != Tile::snow_Id)
{
return false;
}
y += random->nextInt(4);
int height = random->nextInt(4) + 7;
int baseRadius = height / 4 + random->nextInt(2);
if (baseRadius > 1 && random->nextInt(60) == 0)
{
y += 10 + random->nextInt(30);
}
for (int k = 0; k < height; ++k)
{
float f = (1.0F - (float)k / (float)height) * (float)baseRadius;
int l = ceil(f);
for (int ix = -l; ix <= l; ++ix)
{
float f1 = (float)abs(ix) - 0.25F;
for (int iz = -l; iz <= l; ++iz)
{
float f2 = (float)abs(iz) - 0.25F;
if ((ix == 0 && iz == 0 || f1 * f1 + f2 * f2 <= f * f) &&
(ix != -l && ix != l && iz != -l && iz != l || random->nextFloat() <= 0.75F))
{
int currentTile = level->getTile(x + ix, y + k, z + iz);
if (level->isEmptyTile(x + ix, y + k, z + iz) || currentTile == Tile::dirt_Id ||
currentTile == Tile::snow_Id || currentTile == Tile::ice_Id)
{
level->setTileAndData(x + ix, y + k, z + iz, Tile::packedIce_Id, 0, 3);
}
if (k != 0 && l > 1)
{
currentTile = level->getTile(x + ix, y - k, z + iz);
if (level->isEmptyTile(x + ix, y - k, z + iz) || currentTile == Tile::dirt_Id ||
currentTile == Tile::snow_Id || currentTile == Tile::ice_Id)
{
level->setTileAndData(x + ix, y - k, z + iz, Tile::packedIce_Id, 0, 3);
}
}
}
}
}
}
int rootRadius = baseRadius - 1;
if (rootRadius < 0) rootRadius = 0;
else if (rootRadius > 1) rootRadius = 1;
for (int rx = -rootRadius; rx <= rootRadius; ++rx)
{
for (int rz = -rootRadius; rz <= rootRadius; ++rz)
{
int curY = y - 1;
int depthCounter = 50;
if (abs(rx) == 1 && abs(rz) == 1) depthCounter = random->nextInt(5);
while (curY > 50)
{
int t = level->getTile(x + rx, curY, z + rz);
if (!level->isEmptyTile(x + rx, curY, z + rz) && t != Tile::dirt_Id &&
t != Tile::snow_Id && t != Tile::ice_Id && t != Tile::packedIce_Id)
{
break;
}
level->setTileAndData(x + rx, curY, z + rz, Tile::packedIce_Id, 0, 3);
curY--;
depthCounter--;
if (depthCounter <= 0)
{
curY -= (random->nextInt(5) + 1);
depthCounter = random->nextInt(5);
}
}
}
}
return true;
}