1414import net .minecraft .world .level .block .state .BlockState ;
1515import net .minecraft .world .level .chunk .CarvingMask ;
1616import net .minecraft .world .level .chunk .ChunkAccess ;
17- import net .minecraft .world .level .levelgen .Aquifer ;
18- import net .minecraft .world .level .levelgen .Beardifier ;
19- import net .minecraft .world .level .levelgen .DensityFunction ;
20- import net .minecraft .world .level .levelgen .Heightmap ;
17+ import net .minecraft .world .level .levelgen .*;
2118import net .minecraft .world .level .levelgen .carver .CarvingContext ;
2219import net .minecraft .world .level .levelgen .carver .WorldCarver ;
23- import net .minecraft .world .level .levelgen .structure .StructureStart ;
20+ import net .minecraft .world .level .levelgen .structure .*;
21+ import net .minecraft .world .level .levelgen .structure .pieces .PiecesContainer ;
2422
2523import java .util .HashMap ;
24+ import java .util .List ;
25+ import java .util .Map ;
2626import java .util .function .Function ;
2727
2828public class CraterCarver extends WorldCarver <CraterCarverConfig > {
@@ -33,45 +33,47 @@ public CraterCarver(Codec codec) {
3333 super (codec );
3434 }
3535
36- public boolean carve (CarvingContext context , CraterCarverConfig config , ChunkAccess chunk , Function <BlockPos , Holder <Biome >> posToBiome , RandomSource random , Aquifer aquiferSampler , ChunkPos pos , CarvingMask carvingMask ) {
37- //pos = center chunk pos
36+ public boolean carve (CarvingContext context , CraterCarverConfig config , ChunkAccess chunk , Function <BlockPos , Holder <Biome >> posToBiome , RandomSource random , Aquifer aquiferSampler , ChunkPos centerPos , CarvingMask carvingMask ) {
37+ //centerPos = center chunk pos
3838 int xCenterOffset = random .nextInt (16 );//pos
3939 int zCenterOffset = random .nextInt (16 );//pos
40- int initialY = getHeightWithCaching (context , pos .getBlockX (xCenterOffset ), pos .getBlockZ (zCenterOffset ));
40+ int initialY = getHeightWithCaching (context , centerPos .getBlockX (xCenterOffset ), centerPos .getBlockZ (zCenterOffset ));
4141
4242
43- BlockPos craterCenter = pos .getBlockAt (xCenterOffset , initialY , zCenterOffset );
43+ BlockPos craterCenter = centerPos .getBlockAt (xCenterOffset , initialY , zCenterOffset );
4444 BlockPos .MutableBlockPos mutable = craterCenter .mutable ();
4545
4646 double radius = 8 + (random .nextDouble () * (config .maxRadius - config .minRadius ));
4747
4848 //X tilt, Z tilt ?
4949 //we need the height at 4 "corners"
50- int northY = getHeightWithCaching (context , (int ) (pos .getBlockX (xCenterOffset ) - radius ), pos .getBlockZ (zCenterOffset ));//negative X
51- int southY = getHeightWithCaching (context , (int ) (pos .getBlockX (xCenterOffset ) + radius ), pos .getBlockZ (zCenterOffset ));//positive X
52- int westY = getHeightWithCaching (context , pos .getBlockX (xCenterOffset ), (int ) (pos .getBlockZ (zCenterOffset ) - radius ));//negative Z
53- int eastY = getHeightWithCaching (context , pos .getBlockX (xCenterOffset ), (int ) (pos .getBlockZ (zCenterOffset ) + radius ));//positive X
50+ int northY = getHeightWithCaching (context , (int ) (centerPos .getBlockX (xCenterOffset ) - radius ), centerPos .getBlockZ (zCenterOffset ));//negative X
51+ int southY = getHeightWithCaching (context , (int ) (centerPos .getBlockX (xCenterOffset ) + radius ), centerPos .getBlockZ (zCenterOffset ));//positive X
52+ int westY = getHeightWithCaching (context , centerPos .getBlockX (xCenterOffset ), (int ) (centerPos .getBlockZ (zCenterOffset ) - radius ));//negative Z
53+ int eastY = getHeightWithCaching (context , centerPos .getBlockX (xCenterOffset ), (int ) (centerPos .getBlockZ (zCenterOffset ) + radius ));//positive X
5454
5555 double xTilt = (southY - northY )/radius /2 ;
5656 double xStart = ((southY + northY )/2d - initialY )/radius ;
5757 double zTilt = (eastY - westY )/radius /2 ;
5858 double zStart = ((westY + eastY )/2d - initialY )/radius ;
5959
60- double depthMultiplier = (1 - ((random .nextDouble () - 0.5 ) * 0.3 ))*(1 +Math .abs (xTilt )*3 + Math .abs (zTilt )*3 );
60+ double depthMultiplier = (1 - ((random .nextDouble () - 0.5 ) * 0.3 ))*(1 +Math .min ( Math . abs (xTilt )*3 + Math .abs (zTilt )*3 , 6 ) );
6161 boolean fresh = random .nextInt (16 ) == 1 ;
6262
6363 SimpleBitStorage rawData = new SimpleBitStorage (Mth .ceillog2 (chunk .getHeight () + 1 ),256 );
6464
6565
66+ int minBuildHeight = chunk .getMinBuildHeight ();
6667 for (int innerChunkX = 0 ; innerChunkX < 16 ; innerChunkX ++) { //iterate through positions in chunk
6768 for (int innerChunkZ = 0 ; innerChunkZ < 16 ; innerChunkZ ++) {
6869 double xDev = chunk .getPos ().getBlockX (innerChunkX ) - craterCenter .getX ();
6970 double zDev = chunk .getPos ().getBlockZ (innerChunkZ ) - craterCenter .getZ ();
70- int surfaceY = chunk .getHeight (Heightmap .Types .WORLD_SURFACE , innerChunkX , innerChunkZ );
71+ int surfaceY = chunk .getHeight (Heightmap .Types .OCEAN_FLOOR_WG , innerChunkX , innerChunkZ );//this one is not initialised at all.
7172
72- rawData .set (innerChunkX + innerChunkZ *16 ,Math .max (0 ,surfaceY - chunk . getMinBuildHeight () ));
73+ rawData .set (innerChunkX + innerChunkZ *16 ,Math .max (0 ,surfaceY - minBuildHeight + 1 ));
7374
7475 if (xDev > -32 && xDev < 32 && zDev > -32 && zDev < 32 ) {
76+ //chunk.setBlockState(new BlockPos(innerChunkX,surfaceY, innerChunkZ), config.debugSettings.getLavaState(), false);
7577 if (xDev * xDev + zDev * zDev <= radius * radius ) { //distance to crater and depth
7678 xDev /= radius ;
7779 zDev /= radius ;
@@ -80,7 +82,7 @@ public boolean carve(CarvingContext context, CraterCarverConfig config, ChunkAcc
8082 double craterDepth = 5 - yDev ;
8183 craterDepth *= depthMultiplier ;
8284 //if (craterDepth > 0.0) {
83- double toDig = craterDepth - (zDev * zTilt + xDev * xTilt - xStart - zStart )*radius ;
85+ double toDig = craterDepth - (zDev * zTilt + xDev * xTilt + ( xStart + zStart )/ 2 )*radius ;
8486 //}
8587
8688
@@ -97,48 +99,119 @@ public boolean carve(CarvingContext context, CraterCarverConfig config, ChunkAcc
9799 toDig += surfaceY - initialY + 1 ;
98100 mutable .move (Direction .UP , surfaceY - initialY + 1 );
99101 }
100- while (!chunk .getBlockState (mutable ).isAir ()) {
102+ /* while (!chunk.getBlockState(mutable).isAir()) {
101103 mutable.move(Direction.UP);
102104 toDig++;
103- }
105+ }
106+ */
104107 //}
105108 if (toDig > 0 ) {
106109 for (int dug = 0 ; dug < toDig ; dug ++) {
107110 mutable .move (Direction .DOWN );
108111 //carvingMask.get(innerChunkX, mutable.getY() + 64, innerChunkZ);
109- int relativeY = mutable .getY () - chunk .getMinBuildHeight ();
110- if (!chunk .getBlockState (mutable ).isAir () || carvingMask .get (innerChunkX , relativeY , innerChunkZ ) || dug > 0 ) {
111- if (!carvingMask .get (innerChunkX , relativeY , innerChunkZ )) {
112- chunk .setBlockState (mutable , AIR , true );
113- carvingMask .set (innerChunkX , relativeY , innerChunkZ );
114- if (!fresh && dug + 1 >= toDig && !chunk .getBlockState (copy .set (mutable ).move (Direction .DOWN , 2 )).isAir ()) {
115- context .topMaterial (posToBiome , chunk , mutable , true ).ifPresent (blockStates -> chunk .setBlockState (mutable .move (Direction .DOWN ), blockStates , true ));
112+ int relativeY = mutable .getY () - minBuildHeight ;
113+ if (relativeY <=1 ) break ;
114+ try {
115+ if (!chunk .getBlockState (mutable ).isAir () || carvingMask .get (innerChunkX , relativeY , innerChunkZ ) || dug > 0 ) {
116+ if (!carvingMask .get (innerChunkX , relativeY , innerChunkZ )) {
117+ chunk .setBlockState (mutable , AIR , true );//this never manages to update the hightmap correctly. That's why we do a dirt hack
118+ carvingMask .set (innerChunkX , relativeY , innerChunkZ );
119+ if (!fresh && dug + 1 >= toDig && !chunk .getBlockState (copy .set (mutable ).move (Direction .DOWN , 2 )).isAir ()) {
120+ context .topMaterial (posToBiome , chunk , mutable , true ).ifPresent (blockStates -> chunk .setBlockState (mutable .move (Direction .DOWN ), blockStates , true ));
121+ }
116122 }
117123 }
124+ } catch (Exception e ) {
125+ System .out .println ("relative Y :" +relativeY + "| real y :" + mutable .getY ()+"| crater depth :" + (craterDepth - (zDev * zTilt + xDev * xTilt - (xStart + zStart )/2 )*radius ));
126+ throw e ;
118127 }
119128 }
120129 // update the heightmap for the column here
121130 int y = mutable .getY () - 1 ;
122-
123- rawData .set (innerChunkX + innerChunkZ * 16 , Math .max (0 , y - chunk .getMinBuildHeight ()));
131+ //
132+ if (y < minBuildHeight )
133+ System .out .println ("issue with terrain hight at " + chunk .getPos () + " y = " + y );
134+ rawData .set (innerChunkX + innerChunkZ * 16 , Math .max (0 , y - minBuildHeight +1 ));
124135
125136 }
126137 }
127138 }
128139 }
129140 }
130- chunk .setHeightmap (Heightmap .Types .WORLD_SURFACE ,rawData .getRaw ());
131- chunk .setHeightmap (Heightmap .Types .WORLD_SURFACE_WG , rawData .getRaw ());
141+ // chunk.setHeightmap(Heightmap.Types.WORLD_SURFACE,rawData.getRaw());
142+ // chunk.setHeightmap(Heightmap.Types.WORLD_SURFACE_WG, rawData.getRaw());
132143 //adjust the bonding box based on the rawData.
133- chunk .getAllReferences ().forEach ((s , longSet ) -> {
134- StructureStart start = chunk .getStartForStructure (s );
135- if (start != null ) {
136- start .getStructure ().terrainAdaptation ();
137- start .getBoundingBox ();
138- }
144+ Map <Structure , StructureStart > structures = new HashMap <>();
145+ chunk .getAllStarts ().forEach (
146+ (structure , start ) -> {
147+ //we only modify surface structures
148+ if (start != null && start != StructureStart .INVALID_START && structure .step () == GenerationStep .Decoration .SURFACE_STRUCTURES ) {
149+ BoundingBox box = start .getBoundingBox ();
150+ box = structure .terrainAdaptation () != TerrainAdjustment .NONE ? box .inflatedBy (-12 ) : box ;
151+ int references = start .getReferences ();
152+ List <StructurePiece > pieces = start .getPieces ();
153+
154+ int chunkMinX = chunk .getPos ().getMinBlockX ();
155+ int chunkMaxX = chunk .getPos ().getMaxBlockX ();
156+ int chunkMinZ = chunk .getPos ().getMinBlockZ ();
157+ int chunkMaxZ = chunk .getPos ().getMaxBlockZ ();
158+
159+ int minX = Math .max (box .minX (), chunkMinX );
160+ int maxX = Math .min (box .maxX (), chunkMaxX );
161+ int minZ = Math .max (box .minZ (), chunkMinZ );
162+ int maxZ = Math .min (box .maxZ (), chunkMaxZ );
163+ int minY = Math .max (box .minY (), minBuildHeight );
164+ for (int x = minX ; x <= maxX ; x ++) {
165+ for (int z = minZ ; z <= maxZ ; z ++) {
166+ int localX = x & 15 ;
167+ int localZ = z & 15 ;
139168
140- //todo rerun the terrain adaptation. (beard_box only)
141- });
169+ int surfaceY = rawData .get (localX + localZ *16 ) + minBuildHeight ;
170+ if (surfaceY < minY ){
171+ minY = surfaceY ;
172+ }
173+ }
174+ }
175+ BoundingBox finalBox = box ;
176+ int finalMinY = minY ;
177+ pieces .forEach (piece -> piece .move (0 , finalMinY - finalBox .minY (),0 ));
178+ //we move the structure down a bit.
179+ start = new StructureStart (structure , chunk .getPos (), references , new PiecesContainer (pieces ));
180+ structures .put (structure , start );
181+ }
182+ }
183+ );
184+ structures .forEach (chunk ::setStartForStructure );
185+ /*
186+ chunk.getAllReferences().forEach((structure, longSet) -> {
187+ StructureStart start = chunk.getStartForStructure(structure);
188+ if (start != null && start != StructureStart.INVALID_START) {
189+ BoundingBox box = start.getBoundingBox();
190+ box = structure.terrainAdaptation() != TerrainAdjustment.NONE ? box.inflatedBy(-12):box;
191+ // Clamp to this chunk only
192+ int chunkMinX = chunk.getPos().getMinBlockX();
193+ int chunkMaxX = chunk.getPos().getMaxBlockX();
194+ int chunkMinZ = chunk.getPos().getMinBlockZ();
195+ int chunkMaxZ = chunk.getPos().getMaxBlockZ();
196+
197+ int minX = Math.max(box.minX(), chunkMinX);
198+ int maxX = Math.min(box.maxX(), chunkMaxX);
199+ int minZ = Math.max(box.minZ(), chunkMinZ);
200+ int maxZ = Math.min(box.maxZ(), chunkMaxZ);
201+
202+ for (int x = minX; x <= maxX; x++) {
203+ for (int z = minZ; z <= maxZ; z++) {
204+ int localX = x & 15;
205+ int localZ = z & 15;
206+
207+ int surfaceY = rawData.get(localX + localZ*16) + minBuildHeight;
208+ for (int y = surfaceY+1; y < box.minY(); y++) {
209+ chunk.setBlockState(new BlockPos(x, y, z), config.debugSettings.getBarrierState(), false);
210+ }
211+ }
212+ }
213+ }
214+ });*/
142215
143216 return true ;
144217 }
0 commit comments