Files
MinecraftConsoles/Minecraft.World/OreFeature.cpp
Loki Rautio 087b7e7abf Revert "Project modernization (#630)"
This code was not tested and breaks in Release builds, reverting to restore
functionality of the nightly. All in-game menus do not work and generating
a world crashes.

This reverts commit a9be52c41a.
2026-03-07 21:12:22 -06:00

149 lines
4.2 KiB
C++

#include "stdafx.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "OreFeature.h"
void OreFeature::_init(int tile, int count, int targetTile)
{
this->tile = tile;
this->count = count;
this->targetTile = targetTile;
}
OreFeature::OreFeature(int tile, int count)
{
_init(tile, count, Tile::stone_Id);
}
OreFeature::OreFeature(int tile, int count, int targetTile)
{
_init(tile, count, targetTile);
}
bool OreFeature::place(Level *level, Random *random, int x, int y, int z)
{
PIXBeginNamedEvent(0,"Place Ore Feature");
float dir = random->nextFloat() * PI;
double x0 = x + 8 + Mth::sin(dir) * count / 8;
double x1 = x + 8 - Mth::sin(dir) * count / 8;
double z0 = z + 8 + Mth::cos(dir) * count / 8;
double z1 = z + 8 - Mth::cos(dir) * count / 8;
double y0 = y + random->nextInt(3) - 2;
double y1 = y + random->nextInt(3) - 2;
bool collisionsExpected = false;
LevelGenerationOptions *levelGenOptions = NULL;
if( app.getLevelGenerationOptions() != NULL )
{
levelGenOptions = app.getLevelGenerationOptions();
// 4J Stu - Optimise schematic intersection checks by first checking the max possible bounding box of this place call
int minX = x0 - 1;
int minY = y0 - 1;
int minZ = z0 - 1;
double maxss = count / 16;
double maxr = (Mth::sin(PI) + 1) * maxss + 1;
double maxhr = (Mth::sin(PI) + 1) * maxss + 1;
int maxX = Mth::floor(x1 + maxr / 2);
int maxY = Mth::floor(y1 + maxhr / 2);
int maxZ = Mth::floor(z1 + maxr / 2);
collisionsExpected = levelGenOptions->checkIntersects(minX, minY, minZ, maxX, maxY, maxZ);
}
bool doEarlyRejectTest = false;
if( y0 > level->getSeaLevel() )
{
doEarlyRejectTest = true;
}
for (int d = 0; d <= count; d++)
{
double xx = x0 + (x1 - x0) * d / count;
double yy = y0 + (y1 - y0) * d / count;
double zz = z0 + (z1 - z0) * d / count;
double ss = random->nextDouble() * count / 16;
double r = (Mth::sin(d * PI / count) + 1) * ss + 1;
double hr = r; //(Mth::sin(d * PI / count) + 1) * ss + 1;
double halfR = r/2;
double halfHR = halfR; //hr/2;
int xt0 = Mth::floor(xx - halfR);
int yt0 = Mth::floor(yy - halfHR);
int zt0 = Mth::floor(zz - halfR);
int xt1 = Mth::floor(xx + halfR);
int yt1 = Mth::floor(yy + halfHR);
int zt1 = Mth::floor(zz + halfR);
// 4J Stu Added to stop ore features generating areas previously place by game rule generation
if(collisionsExpected && levelGenOptions != NULL)
{
bool intersects = levelGenOptions->checkIntersects(xt0, yt0, zt0, xt1, yt1, zt1);
if(intersects)
{
//app.DebugPrintf("Skipping ore feature generation as it overlaps a game rule structure\n");
continue;
}
}
// A large % of ore placement is entirely into the air. Attempt to identify some of these early, by check the corners
// of the area we are placing in to see if we are going to (very probably) be entirely above the height stored in the heightmap
if( doEarlyRejectTest )
{
bool earlyReject = true;
if ( level->getHeightmap(xt0, zt0) >= yt0 ) earlyReject = false;
else if( level->getHeightmap(xt1, zt0) >= yt0 ) earlyReject = false;
else if( level->getHeightmap(xt0, zt1) >= yt0 ) earlyReject = false;
else if( level->getHeightmap(xt1, zt1) >= yt0 ) earlyReject = false;
if( earlyReject ) continue;
}
double xdxd,ydyd;
double xd0 = ((xt0 + 0.5) - xx);
double yd0 = ((yt0 + 0.5) - yy);
double zd0 = ((zt0 + 0.5) - zz);
double halfRSq = halfR * halfR;
double xd = xd0;
for (int x2 = xt0; x2 <= xt1; x2++, xd++)
{
xdxd = xd * xd;
if (xdxd < halfRSq)
{
double yd = yd0;
for (int y2 = yt0; y2 <= yt1; y2++, yd++)
{
ydyd = yd * yd;
if (xdxd + ydyd < halfRSq)
{
double zd = zd0;
for (int z2 = zt0; z2 <= zt1; z2++, zd++)
{
if (xdxd + ydyd + zd * zd < halfRSq)
{
if ( level->getTile(x2, y2, z2) == targetTile)
{
level->setTileAndData(x2, y2, z2, tile, 0, Tile::UPDATE_INVISIBLE_NO_LIGHT);
}
}
}
}
}
}
}
}
PIXEndNamedEvent();
return true;
}