the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "net.minecraft.world.level.h"
3#include "net.minecraft.world.level.tile.h"
4#include "OreFeature.h"
5
6void OreFeature::_init(int tile, int count, int targetTile)
7{
8 this->tile = tile;
9 this->count = count;
10 this->targetTile = targetTile;
11}
12
13OreFeature::OreFeature(int tile, int count)
14{
15 _init(tile, count, Tile::stone_Id);
16}
17
18OreFeature::OreFeature(int tile, int count, int targetTile)
19{
20 _init(tile, count, targetTile);
21}
22
23bool OreFeature::place(Level *level, Random *random, int x, int y, int z)
24{
25 PIXBeginNamedEvent(0,"Place Ore Feature");
26 float dir = random->nextFloat() * PI;
27
28 double x0 = x + 8 + Mth::sin(dir) * count / 8;
29 double x1 = x + 8 - Mth::sin(dir) * count / 8;
30 double z0 = z + 8 + Mth::cos(dir) * count / 8;
31 double z1 = z + 8 - Mth::cos(dir) * count / 8;
32
33 double y0 = y + random->nextInt(3) - 2;
34 double y1 = y + random->nextInt(3) - 2;
35
36 bool collisionsExpected = false;
37
38 LevelGenerationOptions *levelGenOptions = NULL;
39 if( app.getLevelGenerationOptions() != NULL )
40 {
41 levelGenOptions = app.getLevelGenerationOptions();
42
43 // 4J Stu - Optimise schematic intersection checks by first checking the max possible bounding box of this place call
44 int minX = x0 - 1;
45 int minY = y0 - 1;
46 int minZ = z0 - 1;
47
48 double maxss = count / 16;
49 double maxr = (Mth::sin(PI) + 1) * maxss + 1;
50 double maxhr = (Mth::sin(PI) + 1) * maxss + 1;
51 int maxX = Mth::floor(x1 + maxr / 2);
52 int maxY = Mth::floor(y1 + maxhr / 2);
53 int maxZ = Mth::floor(z1 + maxr / 2);
54
55 collisionsExpected = levelGenOptions->checkIntersects(minX, minY, minZ, maxX, maxY, maxZ);
56 }
57
58 bool doEarlyRejectTest = false;
59 if( y0 > level->getSeaLevel() )
60 {
61 doEarlyRejectTest = true;
62 }
63
64 for (int d = 0; d <= count; d++)
65 {
66 double xx = x0 + (x1 - x0) * d / count;
67 double yy = y0 + (y1 - y0) * d / count;
68 double zz = z0 + (z1 - z0) * d / count;
69
70 double ss = random->nextDouble() * count / 16;
71 double r = (Mth::sin(d * PI / count) + 1) * ss + 1;
72 double hr = r; //(Mth::sin(d * PI / count) + 1) * ss + 1;
73
74 double halfR = r/2;
75 double halfHR = halfR; //hr/2;
76
77 int xt0 = Mth::floor(xx - halfR);
78 int yt0 = Mth::floor(yy - halfHR);
79 int zt0 = Mth::floor(zz - halfR);
80
81 int xt1 = Mth::floor(xx + halfR);
82 int yt1 = Mth::floor(yy + halfHR);
83 int zt1 = Mth::floor(zz + halfR);
84
85 // 4J Stu Added to stop ore features generating areas previously place by game rule generation
86 if(collisionsExpected && levelGenOptions != NULL)
87 {
88 bool intersects = levelGenOptions->checkIntersects(xt0, yt0, zt0, xt1, yt1, zt1);
89 if(intersects)
90 {
91 //app.DebugPrintf("Skipping ore feature generation as it overlaps a game rule structure\n");
92 continue;
93 }
94 }
95
96 // A large % of ore placement is entirely into the air. Attempt to identify some of these early, by check the corners
97 // 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
98
99 if( doEarlyRejectTest )
100 {
101 bool earlyReject = true;
102 if ( level->getHeightmap(xt0, zt0) >= yt0 ) earlyReject = false;
103 else if( level->getHeightmap(xt1, zt0) >= yt0 ) earlyReject = false;
104 else if( level->getHeightmap(xt0, zt1) >= yt0 ) earlyReject = false;
105 else if( level->getHeightmap(xt1, zt1) >= yt0 ) earlyReject = false;
106
107 if( earlyReject ) continue;
108 }
109
110 double xdxd,ydyd;
111
112 double xd0 = ((xt0 + 0.5) - xx);
113 double yd0 = ((yt0 + 0.5) - yy);
114 double zd0 = ((zt0 + 0.5) - zz);
115
116 double halfRSq = halfR * halfR;
117
118 double xd = xd0;
119 for (int x2 = xt0; x2 <= xt1; x2++, xd++)
120 {
121 xdxd = xd * xd;
122 if (xdxd < halfRSq)
123 {
124 double yd = yd0;
125 for (int y2 = yt0; y2 <= yt1; y2++, yd++)
126 {
127 ydyd = yd * yd;
128 if (xdxd + ydyd < halfRSq)
129 {
130 double zd = zd0;
131 for (int z2 = zt0; z2 <= zt1; z2++, zd++)
132 {
133 if (xdxd + ydyd + zd * zd < halfRSq)
134 {
135 if ( level->getTile(x2, y2, z2) == targetTile)
136 {
137 level->setTileAndData(x2, y2, z2, tile, 0, Tile::UPDATE_INVISIBLE_NO_LIGHT);
138 }
139 }
140 }
141 }
142 }
143 }
144 }
145 }
146
147 PIXEndNamedEvent();
148 return true;
149}