Skip to content

Commit 24f2079

Browse files
authored
Fix ore veins with only one layer causing crashes (#4183)
1 parent 158747d commit 24f2079

File tree

3 files changed

+39
-16
lines changed

3 files changed

+39
-16
lines changed

src/main/java/com/gregtechceu/gtceu/api/data/worldgen/GTLayerPattern.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,24 @@ public GTLayerPattern(List<Layer> layers) {
3434
this.layers = layers;
3535
}
3636

37-
public Layer rollNext(@Nullable Layer previous, RandomSource random) {
37+
public @Nullable Layer rollNext(@Nullable Layer previous, RandomSource random) {
38+
if (layers.isEmpty()) return null;
39+
if (layers.size() == 1) return layers.get(0);
40+
3841
int totalWeight = 0;
39-
for (Layer layer : layers)
40-
if (layer != previous)
41-
totalWeight += layer.weight;
42+
for (Layer layer : layers) {
43+
if (layer != previous) totalWeight += layer.weight;
44+
}
45+
// totalWeight should be >0 here but better be safe than sorry
46+
if (totalWeight <= 0) return null;
47+
4248
int rolled = random.nextInt(totalWeight);
4349

4450
for (Layer layer : layers) {
45-
if (layer == previous)
46-
continue;
51+
if (layer == previous) continue;
52+
4753
rolled -= layer.weight;
48-
if (rolled < 0)
49-
return layer;
54+
if (rolled < 0) return layer;
5055
}
5156
return null;
5257
}

src/main/java/com/gregtechceu/gtceu/api/data/worldgen/generator/veins/LayeredVeinGenerator.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ public Map<BlockPos, OreBlockPlacer> generate(WorldGenLevel level, RandomSource
7575
if (patternPool.isEmpty())
7676
return Map.of();
7777

78-
GTLayerPattern layerPattern = patternPool.get(random.nextInt(patternPool.size()));
78+
// minor optimization, usually only one layer pool exists
79+
GTLayerPattern layerPattern = patternPool.size() == 1 ?
80+
patternPool.get(0) : patternPool.get(random.nextInt(patternPool.size()));
7981

8082
int size = entry.clusterSize().sample(random);
8183
float density = entry.density();
@@ -101,37 +103,54 @@ public Map<BlockPos, OreBlockPlacer> generate(WorldGenLevel level, RandomSource
101103

102104
for (int xOffset = 0; xOffset < width; xOffset++) {
103105
float sizeFractionX = xOffset * 2f / width - 1;
104-
if ((sizeFractionX * sizeFractionX) > 1)
106+
float xSizeSqr = sizeFractionX * sizeFractionX;
107+
if (xSizeSqr > 1)
105108
continue;
106109

107110
for (int yOffset = 0; yOffset < height; yOffset++) {
108111
float sizeFractionY = yOffset * 2f / height - 1;
109-
if ((sizeFractionX * sizeFractionX) + (sizeFractionY * sizeFractionY) > 1)
112+
float ySizeSqr = sizeFractionY * sizeFractionY;
113+
if (xSizeSqr + ySizeSqr > 1)
110114
continue;
111115
if (level.isOutsideBuildHeight(yMin + yOffset))
112116
continue;
113117

114118
for (int zOffset = 0; zOffset < length; zOffset++) {
115119
float sizeFractionZ = zOffset * 2f / length - 1;
120+
float zSizeSqr = sizeFractionZ * sizeFractionZ;
121+
// OPTIMIZATION: all values in layerDiameterOffsets are in the [0,1] range, so
122+
// check if the size is >1 before doing any of that math
123+
if (xSizeSqr + ySizeSqr + zSizeSqr > 1)
124+
continue;
116125

117126
int layerIndex = layerCoordinate == 0 ? zOffset : layerCoordinate == 1 ? xOffset : yOffset;
118-
if (slantyCoordinate != layerCoordinate)
127+
if (slantyCoordinate != layerCoordinate) {
119128
layerIndex += Mth.floor(
120129
slantyCoordinate == 0 ? zOffset : slantyCoordinate == 1 ? xOffset : yOffset) * slope;
130+
}
121131

122132
while (layerIndex >= resolvedLayers.size()) {
123133
GTLayerPattern.Layer next = layerPattern.rollNext(
124134
resolvedLayers.isEmpty() ? null : resolvedLayers.get(resolvedLayers.size() - 1),
125135
random);
126-
float offset = random.nextFloat() * .5f + .5f;
136+
137+
float offset = random.nextFloat() * 0.5f + 0.5f;
138+
// insert the previous layer if this one is null (e.g. invalid)
139+
if (next == null) {
140+
if (resolvedLayers.isEmpty()) {
141+
continue;
142+
}
143+
resolvedLayers.add(resolvedLayers.get(resolvedLayers.size() - 1));
144+
layerDiameterOffsets.add(offset);
145+
continue;
146+
}
127147
for (int i = 0; i < next.minSize + random.nextInt(1 + next.maxSize - next.minSize); i++) {
128148
resolvedLayers.add(next);
129149
layerDiameterOffsets.add(offset);
130150
}
131151
}
132152

133-
if ((sizeFractionX * sizeFractionX) + (sizeFractionY * sizeFractionY) +
134-
(sizeFractionZ * sizeFractionZ) > 1 * layerDiameterOffsets.getFloat(layerIndex))
153+
if (xSizeSqr + ySizeSqr + zSizeSqr > layerDiameterOffsets.getFloat(layerIndex))
135154
continue;
136155

137156
GTLayerPattern.Layer layer = resolvedLayers.get(layerIndex);

src/main/java/com/gregtechceu/gtceu/common/data/GTOres.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,6 @@ public class GTOres {
386386
.biomes(BiomeTags.IS_OVERWORLD)
387387
.layeredVeinGenerator(generator -> generator
388388
.withLayerPattern(() -> GTLayerPattern.builder(OVERWORLD_RULES)
389-
.layer(l -> l.weight(3).mat(Coal).size(2, 4))
390389
.layer(l -> l.weight(3).mat(Coal).size(2, 4))
391390
.build()))
392391
.surfaceIndicatorGenerator(indicator -> indicator

0 commit comments

Comments
 (0)