XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

MyDimension

【Java】我的维度模组

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/MyDimension

修改翱翔心境的地形生成代码

8fd27f6
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

5 个文件 +283 -7
Modified build.gradle +2 -3
@@ -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 ]
Modified gradle.properties +1 -1
@@ -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
Modified src/main/java/com/xfestudio/mydimension/registry/ModChunkGenerators.java +4 -0
@@ -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 }
Added src/main/java/com/xfestudio/mydimension/world/SoaringMindChunkGenerator.java +274 -0
@@ -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 }
Modified src/main/resources/data/mydimension/dimension/soaring_mind.json +2 -3
@@ -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 }