|
16 | 16 | import com.github.kevindagame.voxelsniperforge.chunk.ForgeChunk;
|
17 | 17 | import com.github.kevindagame.voxelsniperforge.entity.ForgeEntity;
|
18 | 18 | import com.github.kevindagame.voxelsniperforge.location.ForgeLocation;
|
| 19 | +import com.google.common.collect.ImmutableList; |
| 20 | +import com.google.common.collect.Lists; |
| 21 | +import com.mojang.datafixers.util.Unit; |
19 | 22 |
|
| 23 | +import net.minecraft.Util; |
20 | 24 | import net.minecraft.core.BlockPos;
|
21 | 25 | import net.minecraft.core.Holder;
|
22 | 26 | import net.minecraft.core.QuartPos;
|
23 | 27 | import net.minecraft.core.registries.Registries;
|
24 | 28 | import net.minecraft.resources.ResourceKey;
|
25 | 29 | import net.minecraft.resources.ResourceLocation;
|
| 30 | +import net.minecraft.server.level.ServerChunkCache; |
26 | 31 | import net.minecraft.server.level.ServerLevel;
|
27 | 32 | import net.minecraft.util.RandomSource;
|
| 33 | +import net.minecraft.util.thread.ProcessorMailbox; |
28 | 34 | import net.minecraft.world.entity.Entity;
|
29 | 35 | import net.minecraft.world.entity.EntityType;
|
30 | 36 | import net.minecraft.world.entity.LightningBolt;
|
| 37 | +import net.minecraft.world.level.ChunkPos; |
31 | 38 | import net.minecraft.world.level.WorldGenLevel;
|
32 | 39 | import net.minecraft.world.level.biome.Biome;
|
33 | 40 | import net.minecraft.world.level.biome.BiomeResolver;
|
| 41 | +import net.minecraft.world.level.block.Blocks; |
34 | 42 | import net.minecraft.world.level.chunk.ChunkAccess;
|
35 | 43 | import net.minecraft.world.level.chunk.ChunkGenerator;
|
36 | 44 | import net.minecraft.world.level.chunk.ChunkStatus;
|
| 45 | +import net.minecraft.world.level.chunk.ImposterProtoChunk; |
| 46 | +import net.minecraft.world.level.chunk.LevelChunk; |
37 | 47 | import net.minecraft.world.level.levelgen.Heightmap;
|
38 | 48 | import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
39 | 49 | import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
|
46 | 56 | import java.util.ArrayList;
|
47 | 57 | import java.util.List;
|
48 | 58 | import java.util.Random;
|
| 59 | +import java.util.concurrent.CompletableFuture; |
49 | 60 | import java.util.function.Predicate;
|
50 | 61 |
|
51 | 62 | public record ForgeWorld(@NotNull ServerLevel level) implements IWorld {
|
@@ -109,7 +120,6 @@ public String getName() {
|
109 | 120 |
|
110 | 121 | @Override
|
111 | 122 | public void spawn(BaseLocation location, VoxelEntityType entity) {
|
112 |
| - //TODO test this |
113 | 123 | var tag = EntityType.byString(entity.getKey());
|
114 | 124 | if (tag.isPresent()) {
|
115 | 125 | Entity created = tag.get().create(level);
|
@@ -149,13 +159,67 @@ public void setBiome(int x, int y, int z, VoxelBiome selectedBiome) {
|
149 | 159 |
|
150 | 160 | @Override
|
151 | 161 | public int getHighestBlockYAt(int x, int z) {
|
152 |
| - //TODO test this |
153 | 162 | return level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, new BlockPos(x, 0, z)).getY();
|
154 | 163 | }
|
155 | 164 |
|
156 | 165 | @Override
|
157 | 166 | public void regenerateChunk(int x, int z) {
|
158 |
| - throw new UnsupportedOperationException("Not implemented yet"); |
| 167 | + // copied from net.minecraft.server.commands.ResetChunksCommand, seems to work |
| 168 | + ServerChunkCache serverchunkcache = this.level.getChunkSource(); |
| 169 | + serverchunkcache.chunkMap.debugReloadGenerator(); |
| 170 | + |
| 171 | + // clear all blocks |
| 172 | + final ChunkPos chunkPos = new ChunkPos(x, z); |
| 173 | + if (serverchunkcache.getChunk(x, z, false) != null) { |
| 174 | + for(BlockPos blockpos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), this.level.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), this.level.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) { |
| 175 | + this.level.setBlock(blockpos, Blocks.AIR.defaultBlockState(), 16); |
| 176 | + } |
| 177 | + } |
| 178 | + |
| 179 | + ProcessorMailbox<Runnable> processormailbox = ProcessorMailbox.create(Util.backgroundExecutor(), "worldgen-resetchunks"); |
| 180 | + |
| 181 | + // Generate chunk |
| 182 | + for(ChunkStatus chunkstatus : ImmutableList.of(ChunkStatus.BIOMES, ChunkStatus.NOISE, ChunkStatus.SURFACE, ChunkStatus.CARVERS, ChunkStatus.FEATURES, ChunkStatus.INITIALIZE_LIGHT)) { |
| 183 | + CompletableFuture<Unit> completablefuture = CompletableFuture.supplyAsync(() -> Unit.INSTANCE, processormailbox::tell); |
| 184 | + |
| 185 | + if (serverchunkcache.getChunk(x, z, false) != null) { |
| 186 | + List<ChunkAccess> list = Lists.newArrayList(); |
| 187 | + int range = Math.max(1, chunkstatus.getRange()); |
| 188 | + |
| 189 | + for(int z1 = z - range; z1 <= z + range; ++z1) { |
| 190 | + for(int x1 = x - range; x1 <= x + range; ++x1) { |
| 191 | + ChunkAccess chunkaccess = serverchunkcache.getChunk(x1, z1, chunkstatus.getParent(), true); |
| 192 | + ChunkAccess newChunkaccess; |
| 193 | + if (chunkaccess instanceof ImposterProtoChunk) { |
| 194 | + newChunkaccess = new ImposterProtoChunk(((ImposterProtoChunk)chunkaccess).getWrapped(), true); |
| 195 | + } else if (chunkaccess instanceof LevelChunk) { |
| 196 | + newChunkaccess = new ImposterProtoChunk((LevelChunk)chunkaccess, true); |
| 197 | + } else { |
| 198 | + newChunkaccess = chunkaccess; |
| 199 | + } |
| 200 | + list.add(newChunkaccess); |
| 201 | + } |
| 202 | + } |
| 203 | + |
| 204 | + completablefuture = completablefuture.thenComposeAsync((unit) -> chunkstatus.generate(processormailbox::tell, this.level, serverchunkcache.getGenerator(), this.level.getStructureManager(), serverchunkcache.getLightEngine(), (access) -> { |
| 205 | + throw new UnsupportedOperationException("Not creating full chunks here"); |
| 206 | + }, list).thenApply((either) -> { |
| 207 | + if (chunkstatus == ChunkStatus.NOISE) { |
| 208 | + either.left().ifPresent((access) -> Heightmap.primeHeightmaps(access, ChunkStatus.POST_FEATURES)); |
| 209 | + } |
| 210 | + return Unit.INSTANCE; |
| 211 | + }), processormailbox::tell); |
| 212 | + } |
| 213 | + |
| 214 | + this.level.getServer().managedBlock(completablefuture::isDone); |
| 215 | + } |
| 216 | + |
| 217 | + // fire blockChanged events |
| 218 | + if (serverchunkcache.getChunk(x, z, false) != null) { |
| 219 | + for(BlockPos blockpos1 : BlockPos.betweenClosed(chunkPos.getMinBlockX(), this.level.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), this.level.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) { |
| 220 | + serverchunkcache.blockChanged(blockpos1); |
| 221 | + } |
| 222 | + } |
159 | 223 | }
|
160 | 224 |
|
161 | 225 | @Override
|
|
0 commit comments