返回提交历史
Modified
build.gradle
+2
-3
Modified
gradle.properties
+1
-1
Modified
src/main/java/com/xfestudio/mydimension/registry/ModChunkGenerators.java
+4
-0
Added
src/main/java/com/xfestudio/mydimension/world/SoaringMindChunkGenerator.java
+274
-0
Modified
src/main/resources/data/mydimension/dimension/soaring_mind.json
+2
-3
XFEstudio/MyDimension
修改翱翔心境的地形生成代码
8fd27f6
代码差异
5 个文件
+283
-7
@@ -123,12 +123,11 @@ tasks.register('generatePlayerMindDimensions') {
123
123
soaring_mind : [
124
124
type : 'mydimension:soaring_mind',
125
125
generator: [
126
type : 'mydimension:no_structure_noise',
126
type : 'mydimension:soaring_islands',
127
127
biome_source: [
128
128
type : 'minecraft:multi_noise',
129
129
preset: 'minecraft:overworld'
130
],
131
settings : 'minecraft:floating_islands'
130
]
132
131
]
133
132
]
134
133
]
@@ -11,7 +11,7 @@ loader_version_range=[47,)
11
11
mod_id=mydimension
12
12
mod_name=\u6211\u7684\u7ef4\u5ea6
13
13
mod_license=CC0-1.0
14
mod_version=2.1.0
14
mod_version=2.1.1
15
15
mod_group_id=com.xfestudio.mydimension
16
16
maven_group=com.xfestudio
17
17
archives_base_name=mydimension
@@ -3,6 +3,7 @@ package com.xfestudio.mydimension.registry;
3
3
import com.mojang.serialization.Codec;
4
4
import com.xfestudio.mydimension.MyDimension;
5
5
import com.xfestudio.mydimension.world.NoStructureNoiseChunkGenerator;
6
import com.xfestudio.mydimension.world.SoaringMindChunkGenerator;
6
7
import net.minecraft.core.registries.Registries;
7
8
import net.minecraft.world.level.chunk.ChunkGenerator;
8
9
import net.minecraftforge.registries.DeferredRegister;
@@ -14,4 +15,7 @@ public class ModChunkGenerators {
14
15
15
16
public static final RegistryObject<Codec<? extends ChunkGenerator>> NO_STRUCTURE_NOISE =
16
17
CHUNK_GENERATORS.register("no_structure_noise", () -> NoStructureNoiseChunkGenerator.CODEC);
18
19
public static final RegistryObject<Codec<? extends ChunkGenerator>> SOARING_ISLANDS =
20
CHUNK_GENERATORS.register("soaring_islands", () -> SoaringMindChunkGenerator.CODEC);
17
21
}
@@ -0,0 +1,274 @@
1
package com.xfestudio.mydimension.world;
2
3
import com.mojang.serialization.Codec;
4
import com.mojang.serialization.codecs.RecordCodecBuilder;
5
import java.util.List;
6
import java.util.concurrent.CompletableFuture;
7
import java.util.concurrent.Executor;
8
import java.util.stream.Stream;
9
import net.minecraft.Util;
10
import net.minecraft.core.BlockPos;
11
import net.minecraft.core.HolderLookup;
12
import net.minecraft.server.level.WorldGenRegion;
13
import net.minecraft.world.level.LevelHeightAccessor;
14
import net.minecraft.world.level.NoiseColumn;
15
import net.minecraft.world.level.StructureManager;
16
import net.minecraft.world.level.biome.BiomeManager;
17
import net.minecraft.world.level.biome.BiomeSource;
18
import net.minecraft.world.level.block.Blocks;
19
import net.minecraft.world.level.block.state.BlockState;
20
import net.minecraft.world.level.chunk.ChunkAccess;
21
import net.minecraft.world.level.chunk.ChunkGenerator;
22
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
23
import net.minecraft.world.level.levelgen.GenerationStep;
24
import net.minecraft.world.level.levelgen.Heightmap;
25
import net.minecraft.world.level.levelgen.RandomState;
26
import net.minecraft.world.level.levelgen.blending.Blender;
27
import net.minecraft.world.level.levelgen.structure.StructureSet;
28
29
public class SoaringMindChunkGenerator extends ChunkGenerator {
30
public static final Codec<SoaringMindChunkGenerator> CODEC = RecordCodecBuilder.create(instance -> instance.group(
31
BiomeSource.CODEC.fieldOf("biome_source").forGetter(generator -> generator.biomeSource)
32
).apply(instance, instance.stable(SoaringMindChunkGenerator::new)));
33
34
private static final int MIN_Y = 0;
35
private static final int HEIGHT = 256;
36
private static final int CELL_SIZE = 144;
37
private static final int CELL_MARGIN = 48;
38
private static final int NEIGHBOR_RADIUS = 2;
39
private static final BlockState AIR = Blocks.AIR.defaultBlockState();
40
private static final BlockState GRASS = Blocks.GRASS_BLOCK.defaultBlockState();
41
private static final BlockState DIRT = Blocks.DIRT.defaultBlockState();
42
private static final BlockState STONE = Blocks.STONE.defaultBlockState();
43
44
public SoaringMindChunkGenerator(BiomeSource biomeSource) {
45
super(biomeSource, Util.memoize(holder -> holder.value().getGenerationSettings()));
46
}
47
48
@Override
49
protected Codec<? extends ChunkGenerator> codec() {
50
return CODEC;
51
}
52
53
@Override
54
public ChunkGeneratorStructureState createState(HolderLookup<StructureSet> structureSets, RandomState randomState, long seed) {
55
return ChunkGeneratorStructureState.createForFlat(randomState, seed, this.biomeSource, Stream.empty());
56
}
57
58
@Override
59
public void applyCarvers(WorldGenRegion region, long seed, RandomState randomState, BiomeManager biomeManager,
60
StructureManager structureManager, ChunkAccess chunk, GenerationStep.Carving carving) {
61
}
62
63
@Override
64
public void buildSurface(WorldGenRegion region, StructureManager structureManager, RandomState randomState, ChunkAccess chunk) {
65
}
66
67
@Override
68
public void spawnOriginalMobs(WorldGenRegion region) {
69
}
70
71
@Override
72
public CompletableFuture<ChunkAccess> fillFromNoise(Executor executor, Blender blender, RandomState randomState,
73
StructureManager structureManager, ChunkAccess chunk) {
74
Heightmap oceanFloor = chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.OCEAN_FLOOR_WG);
75
Heightmap worldSurface = chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.WORLD_SURFACE_WG);
76
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
77
int minX = chunk.getPos().getMinBlockX();
78
int minZ = chunk.getPos().getMinBlockZ();
79
80
for (int localX = 0; localX < 16; localX++) {
81
int x = minX + localX;
82
for (int localZ = 0; localZ < 16; localZ++) {
83
int z = minZ + localZ;
84
int topY = topIslandY(x, z);
85
if (topY < MIN_Y) {
86
continue;
87
}
88
89
for (int y = MIN_Y; y <= topY; y++) {
90
BlockState state = blockStateAt(x, y, z, topY);
91
if (state.isAir()) {
92
continue;
93
}
94
chunk.setBlockState(pos.set(localX, y, localZ), state, false);
95
oceanFloor.update(localX, y, localZ, state);
96
worldSurface.update(localX, y, localZ, state);
97
}
98
}
99
}
100
101
return CompletableFuture.completedFuture(chunk);
102
}
103
104
@Override
105
public int getBaseHeight(int x, int z, Heightmap.Types heightmapType, LevelHeightAccessor heightAccessor, RandomState randomState) {
106
int topY = Math.min(topIslandY(x, z), heightAccessor.getMaxBuildHeight() - 1);
107
for (int y = topY; y >= heightAccessor.getMinBuildHeight(); y--) {
108
BlockState state = blockStateAt(x, y, z, topY);
109
if (heightmapType.isOpaque().test(state)) {
110
return y + 1;
111
}
112
}
113
return heightAccessor.getMinBuildHeight();
114
}
115
116
@Override
117
public NoiseColumn getBaseColumn(int x, int z, LevelHeightAccessor heightAccessor, RandomState randomState) {
118
BlockState[] states = new BlockState[heightAccessor.getHeight()];
119
int topY = topIslandY(x, z);
120
for (int index = 0; index < states.length; index++) {
121
int y = heightAccessor.getMinBuildHeight() + index;
122
states[index] = blockStateAt(x, y, z, topY);
123
}
124
return new NoiseColumn(heightAccessor.getMinBuildHeight(), states);
125
}
126
127
@Override
128
public int getSeaLevel() {
129
return -63;
130
}
131
132
@Override
133
public int getMinY() {
134
return MIN_Y;
135
}
136
137
@Override
138
public int getGenDepth() {
139
return HEIGHT;
140
}
141
142
@Override
143
public void addDebugScreenInfo(List<String> info, RandomState randomState, BlockPos pos) {
144
info.add("Soaring Mind islands");
145
}
146
147
private static int topIslandY(int x, int z) {
148
int topY = -1;
149
int baseCellX = Math.floorDiv(x, CELL_SIZE);
150
int baseCellZ = Math.floorDiv(z, CELL_SIZE);
151
152
for (int cellX = baseCellX - NEIGHBOR_RADIUS; cellX <= baseCellX + NEIGHBOR_RADIUS; cellX++) {
153
for (int cellZ = baseCellZ - NEIGHBOR_RADIUS; cellZ <= baseCellZ + NEIGHBOR_RADIUS; cellZ++) {
154
Island island = islandFor(cellX, cellZ);
155
if (island == null) {
156
continue;
157
}
158
159
double dx = (double) (x - island.x()) / island.radiusX();
160
double dz = (double) (z - island.z()) / island.radiusZ();
161
double horizontal = dx * dx + dz * dz;
162
if (horizontal > 1.0D) {
163
continue;
164
}
165
166
double edge = 1.0D - horizontal;
167
int surface = island.y() + (int) Math.round(Math.sqrt(edge) * island.height() * 0.42D);
168
surface += surfaceNoise(x, z, island.seed());
169
topY = Math.max(topY, surface);
170
}
171
}
172
173
return Math.min(topY, HEIGHT - 16);
174
}
175
176
private static BlockState blockStateAt(int x, int y, int z, int topY) {
177
if (topY < MIN_Y || y > topY || y < MIN_Y) {
178
return AIR;
179
}
180
181
int baseCellX = Math.floorDiv(x, CELL_SIZE);
182
int baseCellZ = Math.floorDiv(z, CELL_SIZE);
183
boolean insideIsland = false;
184
185
for (int cellX = baseCellX - NEIGHBOR_RADIUS; cellX <= baseCellX + NEIGHBOR_RADIUS && !insideIsland; cellX++) {
186
for (int cellZ = baseCellZ - NEIGHBOR_RADIUS; cellZ <= baseCellZ + NEIGHBOR_RADIUS; cellZ++) {
187
Island island = islandFor(cellX, cellZ);
188
if (island == null) {
189
continue;
190
}
191
192
int localTop = islandTopAt(x, z, island);
193
if (localTop < MIN_Y || y > localTop) {
194
continue;
195
}
196
197
double dx = (double) (x - island.x()) / island.radiusX();
198
double dz = (double) (z - island.z()) / island.radiusZ();
199
double dy = (double) (y - island.y()) / island.height();
200
double taper = dx * dx + dz * dz + dy * dy * 1.35D;
201
if (taper <= 1.0D || y >= island.y() - 3) {
202
insideIsland = true;
203
break;
204
}
205
}
206
}
207
208
if (!insideIsland) {
209
return AIR;
210
}
211
if (y == topY) {
212
return GRASS;
213
}
214
if (y >= topY - 4) {
215
return DIRT;
216
}
217
return STONE;
218
}
219
220
private static int islandTopAt(int x, int z, Island island) {
221
double dx = (double) (x - island.x()) / island.radiusX();
222
double dz = (double) (z - island.z()) / island.radiusZ();
223
double horizontal = dx * dx + dz * dz;
224
if (horizontal > 1.0D) {
225
return -1;
226
}
227
double edge = 1.0D - horizontal;
228
return island.y() + (int) Math.round(Math.sqrt(edge) * island.height() * 0.42D) + surfaceNoise(x, z, island.seed());
229
}
230
231
private static Island islandFor(int cellX, int cellZ) {
232
long seed = mix(cellX, cellZ);
233
if (randomUnit(seed) > 0.72D) {
234
return null;
235
}
236
237
int centerX = cellX * CELL_SIZE + CELL_MARGIN + randomInt(seed, 0, CELL_SIZE - CELL_MARGIN * 2);
238
int centerZ = cellZ * CELL_SIZE + CELL_MARGIN + randomInt(seed, 1, CELL_SIZE - CELL_MARGIN * 2);
239
int centerY = 78 + randomInt(seed, 2, 76);
240
int radiusX = 16 + randomInt(seed, 3, 32);
241
int radiusZ = 16 + randomInt(seed, 4, 32);
242
int height = 10 + randomInt(seed, 5, 24);
243
return new Island(centerX, centerY, centerZ, radiusX, radiusZ, height, seed);
244
}
245
246
private static int surfaceNoise(int x, int z, long seed) {
247
long mixed = mix(x + (int) seed, z - (int) (seed >>> 32));
248
return randomInt(mixed, 0, 5) - 2;
249
}
250
251
private static int randomInt(long seed, int salt, int bound) {
252
return (int) Math.floorMod(mix(seed + salt * 0x9E3779B97F4A7C15L), bound);
253
}
254
255
private static double randomUnit(long seed) {
256
return (double) (mix(seed) >>> 11) * 0x1.0p-53D;
257
}
258
259
private static long mix(int x, int z) {
260
return mix((long) x * 341873128712L + (long) z * 132897987541L);
261
}
262
263
private static long mix(long value) {
264
value ^= value >>> 33;
265
value *= 0xff51afd7ed558ccdL;
266
value ^= value >>> 33;
267
value *= 0xc4ceb9fe1a85ec53L;
268
value ^= value >>> 33;
269
return value;
270
}
271
272
private record Island(int x, int y, int z, int radiusX, int radiusZ, int height, long seed) {
273
}
274
}
@@ -1,11 +1,10 @@
1
1
{
2
2
"type": "mydimension:soaring_mind",
3
3
"generator": {
4
"type": "mydimension:no_structure_noise",
4
"type": "mydimension:soaring_islands",
5
5
"biome_source": {
6
6
"type": "minecraft:multi_noise",
7
7
"preset": "minecraft:overworld"
8
},
9
"settings": "minecraft:floating_islands"
8
}
10
9
}
11
10
}