Updated stuff

This commit is contained in:
coolGi2007
2021-12-23 05:42:51 +00:00
parent fbf418e31d
commit fff510f315
14 changed files with 99 additions and 1109 deletions
+8 -8
View File
@@ -28,15 +28,15 @@ http://mcforge.readthedocs.io/en/latest/gettingstarted/
* A Java Development Kit (JDK) for Java 16 (recommended) or newer. Visit https://www.oracle.com/java/technologies/downloads/ for installers.
* Git or someway to clone git projects. Visit https://git-scm.com/ for installers.
* Any Java IDE, for example Intellij IDEA and Eclipse. You may also use any other code editors, such as Visual Studio Code. (Optional)
It's better to use IntelliJ IDEA since Eclipse is not supported by Architectury, but it still works.
**If using IntelliJ:**
1. open IDEA and import the build.gradle
2. refresh the Gradle project in IDEA if required
**If using Ecplise:**
Not supported...
**If using IntelliJ:**
1. Open IDEA and import the build.gradle
2. Refresh the Gradle project in IDEA if required
3. Wait for the minecraft jars to generate
Side note: invalidate caches and restart if required
## Compiling
@@ -49,7 +49,7 @@ Side note: invalidate caches and restart if required
**If in terminal:**
1. `git clone -b 1.17.1 --recurse-submodules https://gitlab.com/jeseibel/minecraft-lod-mod.git`
2. `cd minecraft-lod-mod`
3. `./gradlew build`
3. `./gradlew assemble` or `./gradlew build`
4. The build should be in `fabric/build/libs/` and `forge/build/libs/`
@@ -68,8 +68,8 @@ Source code uses Mojang mappings.
## Useful commands
Build only Fabric: `./gradlew fabric:build`\
Build only Forge: `./gradlew forge:build`\
Build only Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build`\
Build only Forge: `./gradlew fabric:assemble` or `./gradlew forge:build`\
Run the Fabric client (for debugging): `./gradlew fabric:runClient`\
Run the Forge client (for debugging): `./gradlew forge:runClient`
@@ -1,6 +1,7 @@
package com.seibel.lod.common;
import com.seibel.lod.common.forge.LodForgeMethodCaller;
import com.seibel.lod.common.networking.NetworkInterface;
import com.seibel.lod.common.wrappers.DependencySetup;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.seibel.lod.core.ModInfo;
@@ -13,6 +14,7 @@ public class LodCommonMain {
public static boolean forge = false;
public static boolean serverSided;
public static LodForgeMethodCaller forgeMethodCaller;
public static NetworkInterface networkInterface;
public static void startup(LodForgeMethodCaller caller, boolean serverSided) {
LodCommonMain.serverSided = serverSided;
@@ -24,8 +26,11 @@ public class LodCommonMain {
DependencySetup.createInitialBindings();
}
public static void initConfig() {
ConfigGui.init(ModInfo.ID, Config.class);
}
public static void registerNetworking(NetworkInterface networkInterface) {
LodCommonMain.networkInterface = networkInterface;
}
}
@@ -9,6 +9,11 @@ import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
import java.util.Random;
/**
* used for calling methods that forge modified
* (forge modifies vanilla methods for some reason)
* @author Ran
*/
public interface LodForgeMethodCaller {
List<BakedQuad> getQuads(MinecraftWrapper mc, Block block, BlockState blockState, Direction direction, Random random);
}
@@ -0,0 +1,12 @@
package com.seibel.lod.common.networking;
import net.minecraft.network.FriendlyByteBuf;
/**
* @author Ran
*/
public interface NetworkInterface {
void send(FriendlyByteBuf packetByteBuf);
FriendlyByteBuf receive();
}
@@ -0,0 +1,23 @@
package com.seibel.lod.common.networking;
import com.seibel.lod.common.LodCommonMain;
import io.netty.buffer.Unpooled;
import net.minecraft.network.FriendlyByteBuf;
import java.nio.charset.StandardCharsets;
/**
* This class holds most of the networking code for the mod.
* @author Ran
*/
public class Networking {
// public void example(int packetId) {
// FriendlyByteBuf packetByteBuf = Networking.createNew();
// packetByteBuf.writeInt(packetId);
// LodCommonMain.networkInterface.send(packetByteBuf);
// }
public static FriendlyByteBuf createNew() {
return new FriendlyByteBuf(Unpooled.buffer());
}
}
@@ -19,14 +19,12 @@
package com.seibel.lod.common.wrappers;
import com.seibel.lod.common.wrappers.worldGeneration.ExperimentalGenerator;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractExperimentalWorldGeneratorWrapper;
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractWorldGeneratorWrapper;
import com.seibel.lod.common.wrappers.block.BlockPosWrapper;
import com.seibel.lod.common.wrappers.chunk.ChunkPosWrapper;
@@ -84,9 +82,4 @@ public class WrapperFactory implements IWrapperFactory {
public AbstractWorldGeneratorWrapper createWorldGenerator(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper) {
return new WorldGeneratorWrapper(newLodBuilder, newLodDimension, worldWrapper);
}
@Override
public AbstractExperimentalWorldGeneratorWrapper createExperimentalWorldGenerator(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper) {
return new ExperimentalGenerator(newLodBuilder, newLodDimension, worldWrapper);
}
}
@@ -5,6 +5,7 @@ import com.moandjiezana.toml.Toml;
// TomlWriter is threadsave while Writer is not
import com.moandjiezana.toml.TomlWriter;
import com.mojang.blaze3d.vertex.PoseStack;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.core.ModInfo;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
@@ -52,6 +53,14 @@ import java.util.regex.Pattern;
// This config should work for both Fabric and Forge as long as you use Mojang mappings
@SuppressWarnings("unchecked")
public abstract class ConfigGui {
/*
TODO list
Make wiki
Make it so you can enable and disable buttons from showing
Make min and max not final
Move the ConfigScreenConfigs class to the config class that extends this
*/
/*
List of hacky things that are done that should be done properly
@@ -103,9 +112,10 @@ public abstract class ConfigGui {
// Save and read the file
try {
new Toml().read(Files.newBufferedReader(path)).to(config);
new Toml().read(path.toFile()).to(config);
// new Toml().read(path.toFile()).
} catch (Exception e) {
write(modid);
createFile(modid);
}
for (EntryInfo info : entries) {
@@ -123,9 +133,9 @@ public abstract class ConfigGui {
for (Field field : config.getFields()) {
EntryInfo info = new EntryInfo();
if (field.isAnnotationPresent(Entry.class) || field.isAnnotationPresent(Comment.class) || field.isAnnotationPresent(ScreenEntry.class))
// TODO[CONFIG]: Fix the check for client/server
// if (Minecraft.getInstance().getEnvironmentType() == EnvType.CLIENT)
initClient(modid, field, info);
// If putting in your own mod then put your own check for server sided
if (!LodCommonMain.serverSided)
initClient(modid, field, info);
if (field.isAnnotationPresent(Entry.class))
try {
info.defaultValue = field.get(null);
@@ -140,7 +150,6 @@ public abstract class ConfigGui {
}
private static void initClient(String modid, Field field, EntryInfo info) {
// This adds the buttons to the queue to be rendered
// DONT CALL ON SERVER AS SERVERS CANT RENDER STUFF
Class<?> type = field.getType();
Category c = field.getAnnotation(Category.class);
Entry e = field.getAnnotation(Entry.class);
@@ -221,12 +230,11 @@ public abstract class ConfigGui {
}
// Creates the modid.toml
public static void write(String modid) {
private static void createFile(String modid) {
path = Minecraft.getInstance().gameDirectory.toPath().resolve("config").resolve(modid + ".toml");
try {
if (!Files.exists(path))
Files.createFile(path);
tomlWriter.write(configClass.get(modid).getDeclaredConstructor().newInstance());
} catch (Exception e) {
e.printStackTrace();
}
@@ -260,9 +268,9 @@ public abstract class ConfigGui {
}
private void loadValues() {
try {
new Toml().read(Files.newBufferedReader(path)).to(configClass.get(modid));
new Toml().read(path.toFile()).to(configClass.get(modid));
} catch (Exception e) {
write(modid);
createFile(modid);
}
for (EntryInfo info : entries) {
@@ -290,7 +298,7 @@ public abstract class ConfigGui {
info.field.set(null, info.value);
} catch (IllegalAccessException ignored) {}
}
write(modid);
createFile(modid);
Objects.requireNonNull(minecraft).setScreen(parent);
}));
@@ -1,175 +0,0 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.common.wrappers.world.WorldWrapper;
import com.seibel.lod.common.wrappers.worldGeneration.WorldGenerationStep.GenerationEvent;
import com.seibel.lod.common.wrappers.worldGeneration.WorldGenerationStep.Steps;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.objects.PosToGenerateContainer;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractExperimentalWorldGeneratorWrapper;
import net.minecraft.world.level.ChunkPos;
public class ExperimentalGenerator extends AbstractExperimentalWorldGeneratorWrapper {
private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public WorldGenerationStep generationGroup;
public LodDimension targetLodDim;
public static final int generationGroupSize = 4;
public static final int generationGroupSizeFar = 0;
public static int numberOfGenerationPoints = CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads()*2;
private int estimatedSampleNeeded = 128;
private LinkedList<GenerationEvent> events = new LinkedList<GenerationEvent>();
public ExperimentalGenerator(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper) {
super(newLodBuilder, newLodDimension, worldWrapper);
System.out.println("================ExperimentalGenerator INIT=============");
generationGroup = new WorldGenerationStep(((WorldWrapper) worldWrapper).getServerWorld(), newLodBuilder,
newLodDimension);
}
private boolean checkIfPositionIsValid(int chunkX, int chunkZ, int range) {
for (GenerationEvent event : events) {
if (event.tooClose(chunkX, chunkZ, range)) return false;
}
return true;
}
@Override
public void queueGenerationRequests(LodDimension lodDim, LodBuilder lodBuilder) {
DistanceGenerationMode mode = CONFIG.client().worldGenerator().getDistanceGenerationMode();
numberOfGenerationPoints = CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads();
if (mode == DistanceGenerationMode.NONE || !MC.hasSinglePlayerServer())
return;
// Update all current out standing jobs
Iterator<GenerationEvent> iter = events.iterator();
while (iter.hasNext()) {
GenerationEvent event = iter.next();
if (event.isCompleted()) {
event.join();
iter.remove();
} else if (event.hasTimeout(5, TimeUnit.SECONDS)) {
System.err.println(event.id+": Timed out and terminated!");
event.terminate();
iter.remove();
}
}
// If we still all jobs running, return.
if (events.size() >= numberOfGenerationPoints)
return;
final int targetToGenerate = numberOfGenerationPoints - events.size();
int toGenerate = targetToGenerate;
int positionGoneThough = 0;
// round the player's block position down to the nearest chunk BlockPos
int playerPosX = MC.getPlayerBlockPos().getX();
int playerPosZ = MC.getPlayerBlockPos().getZ();
// TODO: Make it so that lodDim allows feeding in a function to fast halt if
// position generation is completed.
PosToGenerateContainer posToGenerate = lodDim.getPosToGenerate(estimatedSampleNeeded, playerPosX, playerPosZ);
// Find the max number of iterations we need to go though.
// We are checking one FarPos, and one NearPos per iterations. This ensure we
// aren't just
// always picking one or the other.
int nearCount = posToGenerate.getNumberOfNearPos();
int farCount = posToGenerate.getNumberOfFarPos();
int maxIteration = Math.max(nearCount, farCount);
for (int i = 0; i < maxIteration; i++) {
// We have nearPos to go though
if (i < nearCount && posToGenerate.getNthDetail(i, true) != 0) {
positionGoneThough++;
// TODO: Add comment here on why theres a '-1'.
// Not sure what's happening here. This is copied from previous codes.
byte detailLevel = (byte) (posToGenerate.getNthDetail(i, true) - 1);
int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, true));
int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, true));
if (checkIfPositionIsValid(chunkX, chunkZ, generationGroupSize)) {
ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
events.add(new GenerationEvent(chunkPos, generationGroupSize, generationGroup, Steps.Surface));
toGenerate--;
}
}
//if (toGenerate <= 0)
// break;
// We have farPos to go though
if (i < farCount && posToGenerate.getNthDetail(i, false) != 0) {
positionGoneThough++;
// TODO: Add comment here on why theres a '-1'.
// Not sure what's happening here. This is copied from previous codes.
byte detailLevel = (byte) (posToGenerate.getNthDetail(i, false) - 1);
int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, false));
int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, false));
if (checkIfPositionIsValid(chunkX, chunkZ, generationGroupSizeFar)) {
ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
events.add(new GenerationEvent(chunkPos, generationGroupSizeFar, generationGroup, Steps.Surface));
toGenerate--;
}
}
if (toGenerate <= 0)
break;
}
if (targetToGenerate != toGenerate) {
if (toGenerate <= 0) {
System.out.println(
"WorldGenerator: Sampled " + posToGenerate.getNumberOfPos() + " out of " + estimatedSampleNeeded
+ " points, started all targeted " + targetToGenerate + " generations.");
} else {
System.out.println("WorldGenerator: Sampled " + posToGenerate.getNumberOfPos() + " out of "
+ estimatedSampleNeeded + " points, started " + (targetToGenerate - toGenerate)
+ " out of targeted " + targetToGenerate + " generations.");
}
}
if (toGenerate > 0 && estimatedSampleNeeded <= posToGenerate.getNumberOfPos()) {
// We failed to generate enough points from the samples.
// Let's increase the estimatedSampleNeeded.
estimatedSampleNeeded *= 1.3;
// Ensure wee don't go to basically infinity
if (estimatedSampleNeeded > 32768)
estimatedSampleNeeded = 32768;
System.out.println("WorldGenerator: Increasing estimatedSampleNeeeded to " + estimatedSampleNeeded);
} else if (toGenerate <= 0 && positionGoneThough * 1.5 < posToGenerate.getNumberOfPos()) {
// We haven't gone though half of them and it's already enough.
// Let's shink the estimatedSampleNeeded.
estimatedSampleNeeded /= 1.2;
// Ensure we don't go to near zero.
if (estimatedSampleNeeded < 4)
estimatedSampleNeeded = 4;
System.out.println("WorldGenerator: Decreasing estimatedSampleNeeeded to " + estimatedSampleNeeded);
}
}
@Override
public void stop() {
System.out.println("================ExperimentalGenerator SHUTDOWN=============");
generationGroup.executors.shutdownNow();
}
}
@@ -1,902 +0,0 @@
package com.seibel.lod.common.wrappers.worldGeneration;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.LodBuilderConfig;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.objects.lod.LodDimension;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import com.seibel.lod.common.wrappers.worldGeneration.WorldGenerationStep.Steps;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.entity.ai.village.VillageSiege;
import net.minecraft.world.entity.npc.CatSpawner;
import net.minecraft.world.entity.npc.WanderingTraderSpawner;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.chunk.*;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.core.MappedRegistry;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.PatrolSpawner;
import net.minecraft.world.level.levelgen.PhantomSpawner;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.storage.ServerLevelData;
import net.minecraft.world.level.storage.WorldData;
public class WorldGenerationStep {
/*
public static class ChunkScanner implements ChunkScanAccess {
@Override
public CompletableFuture<Void> scanChunk(ChunkPos paramChunkPos, StreamTagVisitor paramStreamTagVisitor) {
// TODO Auto-generated method stub
return null;
}
}*/
public static class GenerationEvent {
private static int generationFutureDebugIDs = 0;
ChunkPos pos;
int range;
Future<?> future;
long nanotime;
int id;
Steps target;
public GenerationEvent(ChunkPos pos, int range, WorldGenerationStep generationGroup, Steps target) {
nanotime = System.nanoTime();
this.pos = pos;
this.range = range;
id = generationFutureDebugIDs++;
this.target = target;
future = generationGroup.executors.submit(() -> {
generationGroup.generateLodFromList(this);
});
}
public boolean isCompleted() {
return future.isDone();
}
public boolean hasTimeout(int duration, TimeUnit unit) {
long currentTime = System.nanoTime();
long delta = currentTime - nanotime;
return (delta > TimeUnit.NANOSECONDS.convert(duration, unit));
}
public void terminate() {
future.cancel(true);
}
public void join() {
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
public boolean tooClose(int cx, int cz, int cr) {
int dist = Math.min(Math.abs(cx - pos.x), Math.abs(cz - pos.z));
return dist<range+cr;
}
public void refreshTimeout() {
nanotime = System.nanoTime();
}
@Override
public String toString() {
return id + ":"+ range + "@"+ pos+"("+target+")";
}
}
private static <T> T joinAsync(CompletableFuture<T> f) {
//while (!f.isDone()) Thread.yield();
return f.join();
}
ServerLevel level;
ChunkGenerator generator;
StructureManager structures;
BiomeManager biomeManager;
WorldGenSettings worldGenSettings;
ThreadedLevelLightEngine lightEngine;
LodBuilder lodBuilder;
LodDimension lodDim;
StructureFeatureManager structureFeatureManager;
// StructureCheck structureCheck;
Registry<Biome> biomes;
RegistryAccess registry;
long worldSeed;
//public ExecutorService executors = Executors.newWorkStealingPool();
public ExecutorService executors = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
//public ExecutorService executors = Executors.newFixedThreadPool(8, new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
public WorldGenerationStep(ServerLevel level, LodBuilder lodBuilder, LodDimension lodDim) {
System.out.println("================WORLD_GEN_STEP_INITING=============");
this.level = level;
this.lodBuilder = lodBuilder;
this.lodDim = lodDim;
setupStuff();
StepStructureStart.onLevelLoad(generator, worldGenSettings, registry, structureFeatureManager, structures, worldSeed);
StepStructureReference.onLevelLoad(level, generator, structureFeatureManager);
StepBiomes.onLevelLoad(level, generator, biomes, structureFeatureManager);
StepNoise.onLevelLoad(level, generator, structureFeatureManager);
StepSurface.onLevelLoad(level, generator, structureFeatureManager);
StepCarvers.onLevelLoad(level, generator, structureFeatureManager, worldSeed, biomeManager);
StepFeatures.onLevelLoad(level, generator, structureFeatureManager, lightEngine);
StepLight.onLevelLoad(lightEngine);
}
private void setupStuff() {
lightEngine = (ThreadedLevelLightEngine) level.getLightEngine();
MinecraftServer server = level.getServer();
WorldData worldData = server.getWorldData();
worldGenSettings = worldData.worldGenSettings();
registry = server.registryAccess();
biomes = registry.registryOrThrow(Registry.BIOME_REGISTRY);
worldSeed = worldGenSettings.seed();
long biomeSeed = BiomeManager.obfuscateSeed(worldSeed);
// FIXME: broken in 1.17.1
// biomeManager = new BiomeManager(level, biomeSeed);
structures = server.getStructureManager();
// TODO: Get the current level dimension
MappedRegistry<LevelStem> mappedRegistry = worldGenSettings.dimensions();
LevelStem levelStem = mappedRegistry.get(LevelStem.OVERWORLD);
if (levelStem == null) {
throw new RuntimeException("There should already be a level.... Right???");
} else {
generator = levelStem.generator();
}
structureFeatureManager = new StructureFeatureManager(level, worldGenSettings);
}
public static final class GridList<T> extends ArrayList<T> implements List<T> {
private static final long serialVersionUID = 1585978374811888116L;
public final int gridCentreToEdge;
public final int gridSize;
public GridList(int gridCentreToEdge) {
super((gridCentreToEdge * 2 + 1) * (gridCentreToEdge * 2 + 1));
gridSize = gridCentreToEdge * 2 + 1;
this.gridCentreToEdge = gridCentreToEdge;
}
public final int offsetOf(int index, int x, int y) {
return index + x + y * gridSize;
}
public GridList<T> subGrid(int centreIndex, int gridCentreToEdge) {
GridList<T> subGrid = new GridList<T>(gridCentreToEdge);
for (int oy = -gridCentreToEdge; oy <= gridCentreToEdge; oy++) {
int begin = offsetOf(centreIndex, -gridCentreToEdge, oy);
int end = offsetOf(centreIndex, gridCentreToEdge, oy);
subGrid.addAll(this.subList(begin, end+1));
}
//System.out.println("========================================\n"+
//this.toDetailString() + "\nTOOOOOOOOOOOOO\n"+subGrid.toDetailString()+
//"==========================================\n");
return subGrid;
}
@Override
public String toString() {
return "GridList "+gridSize+"*"+gridSize+"["+size()+"]";
}
public String toDetailString() {
StringBuilder str = new StringBuilder("\n");
int i = 0;
for (T t : this) {
str.append(t.toString());
str.append(", ");
i++;
if (i%gridSize == 0) {
str.append("\n");
}
}
return str.toString();
}
}
public static class ChunkSynconizer {
private ReentrantLock uniqueOwnerLock = new ReentrantLock();
ChunkAccess chunk;
Steps completedStep = Steps.Empty;
public ChunkSynconizer(ChunkPos pos, ServerLevel level) {
chunk = new ProtoChunk(pos, UpgradeData.EMPTY, level);
}
public boolean tryClaimOwnerLock() {
return uniqueOwnerLock.tryLock();
}
public void releaseOwnerLock() {
uniqueOwnerLock.unlock();
}
public boolean hasCompletedStep(Steps step) {
return step.compareTo(completedStep) <= 0;
}
public void set(ChunkAccess newChunk, Steps newStep) {
chunk = newChunk;
completedStep = newStep;
}
public void set(Steps newStep) {
completedStep = newStep;
}
@Override
public String toString() {
return chunk.getPos().toString();
}
}
ConcurrentHashMap<Long, ChunkSynconizer> chunks = new ConcurrentHashMap<Long, ChunkSynconizer>();
// No longer using Long2ObjectLinkedOpenHashMap as I doubt it is multithread
// safe.
private static final long toLongPos(int cx, int cy) {
return ChunkPos.asLong(cx, cy);
}
private final ChunkSynconizer getChunkSynconizer(long pos) {
ChunkSynconizer chunk = chunks.get(pos);
if (chunk != null)
return chunk;
chunk = new ChunkSynconizer(new ChunkPos(pos), level);
ChunkSynconizer oldVal = chunks.putIfAbsent(pos, chunk);
if (oldVal != null)
return oldVal;
return chunk;
}
public void generateLodFromList(GenerationEvent event) {
try {
System.out.println("Started event: "+event);
GridList<ChunkSynconizer> referencedChunks;
DistanceGenerationMode generationMode;
Runnable lambda = () -> {event.refreshTimeout();};
switch (event.target) {
case Empty:
return;
case StructureStart:
referencedChunks = generateStructureStart(lambda, event.pos, event.range);
generationMode = DistanceGenerationMode.NONE;
break;
case StructureReference:
referencedChunks = generateStructureReference(lambda, event.pos, event.range);
generationMode = DistanceGenerationMode.NONE;
break;
case Biomes:
referencedChunks = generateBiomes(lambda, event.pos, event.range);
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
break;
case Noise:
referencedChunks = generateNoise(lambda, event.pos, event.range);
generationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
break;
case Surface:
referencedChunks = generateSurface(lambda, event.pos, event.range);
generationMode = DistanceGenerationMode.SURFACE;
break;
case Carvers:
referencedChunks = generateCarvers(lambda, event.pos, event.range);
generationMode = DistanceGenerationMode.SURFACE;
break;
case Features:
referencedChunks = generateFeatures(lambda, event.pos, event.range);
generationMode = DistanceGenerationMode.FEATURES;
break;
case LiquidCarvers:
return;
case Light:
return;
default:
return;
}
int centreIndex = referencedChunks.size() / 2;
for (int ox = -event.range; ox <= event.range; ox++) {
for (int oy = -event.range; oy <= event.range; oy++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkSynconizer target = referencedChunks.get(targetIndex);
lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(target.chunk), new LodBuilderConfig(generationMode));
}
}
lambda.run();
for (ChunkSynconizer sync : referencedChunks) {
chunks.remove(sync.chunk.getPos().toLong());
}
System.out.println("Ended event: "+event);
} catch (RuntimeException e) {
e.printStackTrace();
throw e;
}
}
public GridList<ChunkSynconizer> generateStructureStart(Runnable r, ChunkPos pos, int range) {
int cx = pos.x;
int cy = pos.z;
GridList<ChunkSynconizer> chunks = new GridList<ChunkSynconizer>(range);
for (int oy = -range; oy <= range; oy++) {
for (int ox = -range; ox <= range; ox++) {
ChunkSynconizer target = getChunkSynconizer(toLongPos(cx + ox, cy + oy));
chunks.add(target);
if (!target.hasCompletedStep(Steps.StructureStart)) {
boolean owned = target.tryClaimOwnerLock();
if (owned) {
try {
ChunkAccess access = target.chunk;
target.set(StepStructureStart.generate(access),
Steps.StructureStart);
} finally {
target.releaseOwnerLock();
}
}
}
}
}
r.run();
return chunks;
}
public GridList<ChunkSynconizer> generateStructureReference(Runnable r, ChunkPos pos, int range) {
int prestepRange = range + StepStructureReference.RANGE;
GridList<ChunkSynconizer> referencedChunks = generateStructureStart(r, pos, prestepRange);
int centreIndex = referencedChunks.size() / 2;
for (int oy = -range; oy <= range; oy++) {
for (int ox = -range; ox <= range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkSynconizer target = referencedChunks.get(targetIndex);
if (!target.hasCompletedStep(Steps.StructureReference)) {
boolean owned = target.tryClaimOwnerLock();
if (owned) {
try {
GridList<ChunkSynconizer> reference = referencedChunks.subGrid(targetIndex,
StepStructureReference.RANGE);
ArrayList<ChunkAccess> referenceAccess = new ArrayList<ChunkAccess>(reference.size());
for (ChunkSynconizer ref : reference) {
referenceAccess.add(ref.chunk);
}
StepStructureReference.generate(referenceAccess, target.chunk);
target.set(Steps.StructureReference);
} finally {
target.releaseOwnerLock();
}
}
}
}
}
r.run();
return referencedChunks;
}
public GridList<ChunkSynconizer> generateBiomes(Runnable r, ChunkPos pos, int range) {
int prestepRange = range + 1;
GridList<ChunkSynconizer> referencedChunks = generateStructureReference(r, pos, prestepRange);
int centreIndex = referencedChunks.size() / 2;
for (int oy = -range; oy <= range; oy++) {
for (int ox = -range; ox <= range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkSynconizer target = referencedChunks.get(targetIndex);
if (!target.hasCompletedStep(Steps.Biomes)) {
boolean owned = target.tryClaimOwnerLock();
if (owned) {
try {
GridList<ChunkSynconizer> reference = referencedChunks.subGrid(targetIndex,
StepBiomes.RANGE);
ArrayList<ChunkAccess> referenceAccess = new ArrayList<ChunkAccess>(reference.size());
for (ChunkSynconizer ref : reference) {
referenceAccess.add(ref.chunk);
}
target.set(StepBiomes.generate(referenceAccess, target.chunk, executors), Steps.Biomes);
} finally {
target.releaseOwnerLock();
}
}
}
}
}
r.run();
return referencedChunks;
}
public GridList<ChunkSynconizer> generateNoise(Runnable r, ChunkPos pos, int range) {
int prestepRange = range + 1;
GridList<ChunkSynconizer> referencedChunks = generateBiomes(r, pos, prestepRange);
int centreIndex = referencedChunks.size() / 2;
for (int oy = -range; oy <= range; oy++) {
for (int ox = -range; ox <= range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkSynconizer target = referencedChunks.get(targetIndex);
if (!target.hasCompletedStep(Steps.Noise)) {
boolean owned = target.tryClaimOwnerLock();
if (owned) {
try {
GridList<ChunkSynconizer> reference = referencedChunks.subGrid(targetIndex,
StepNoise.RANGE);
ArrayList<ChunkAccess> referenceAccess = new ArrayList<ChunkAccess>(reference.size());
for (ChunkSynconizer ref : reference) {
referenceAccess.add(ref.chunk);
}
target.set(StepNoise.generate(referenceAccess, target.chunk, executors),
Steps.Noise);
} finally {
target.releaseOwnerLock();
}
}
}
}
}
r.run();
return referencedChunks;
}
public GridList<ChunkSynconizer> generateSurface(Runnable r, ChunkPos pos, int range) {
int prestepRange = range + 1;
GridList<ChunkSynconizer> referencedChunks = generateNoise(r, pos, prestepRange);
int centreIndex = referencedChunks.size() / 2;
for (int oy = -range; oy <= range; oy++) {
for (int ox = -range; ox <= range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkSynconizer target = referencedChunks.get(targetIndex);
if (!target.hasCompletedStep(Steps.Surface)) {
boolean owned = target.tryClaimOwnerLock();
if (owned) {
try {
GridList<ChunkSynconizer> reference = referencedChunks.subGrid(targetIndex,
StepSurface.RANGE);
ArrayList<ChunkAccess> referenceAccess = new ArrayList<ChunkAccess>(reference.size());
for (ChunkSynconizer ref : reference) {
referenceAccess.add(ref.chunk);
}
target.set(StepSurface.generate(referenceAccess, target.chunk),
Steps.Surface);
} finally {
target.releaseOwnerLock();
}
}
}
}
}
r.run();
return referencedChunks;
}
public GridList<ChunkSynconizer> generateCarvers(Runnable r, ChunkPos pos, int range) {
int prestepRange = range + 1;
GridList<ChunkSynconizer> referencedChunks = generateSurface(r, pos, prestepRange);
int centreIndex = referencedChunks.size() / 2;
for (int oy = -range; oy <= range; oy++) {
for (int ox = -range; ox <= range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkSynconizer target = referencedChunks.get(targetIndex);
if (!target.hasCompletedStep(Steps.Carvers)) {
boolean owned = target.tryClaimOwnerLock();
if (owned) {
try {
GridList<ChunkSynconizer> reference = referencedChunks.subGrid(targetIndex,
StepCarvers.RANGE);
ArrayList<ChunkAccess> referenceAccess = new ArrayList<ChunkAccess>(reference.size());
for (ChunkSynconizer ref : reference) {
referenceAccess.add(ref.chunk);
}
target.set(StepCarvers.generate(referenceAccess, target.chunk),
Steps.Carvers);
} finally {
target.releaseOwnerLock();
}
}
}
}
}
r.run();
return referencedChunks;
}
public GridList<ChunkSynconizer> generateFeatures(Runnable r, ChunkPos pos, int range) {
int prestepRange = range + 1;
GridList<ChunkSynconizer> referencedChunks = generateCarvers(r, pos, prestepRange);
int centreIndex = referencedChunks.size() / 2;
for (int oy = -range; oy <= range; oy++) {
for (int ox = -range; ox <= range; ox++) {
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkSynconizer target = referencedChunks.get(targetIndex);
if (!target.hasCompletedStep(Steps.Features)) {
boolean owned = target.tryClaimOwnerLock();
if (owned) {
try {
GridList<ChunkSynconizer> reference = referencedChunks.subGrid(targetIndex,
StepFeatures.RANGE);
ArrayList<ChunkAccess> referenceAccess = new ArrayList<ChunkAccess>(reference.size());
for (ChunkSynconizer ref : reference) {
referenceAccess.add(ref.chunk);
}
target.set(StepFeatures.generate(referenceAccess, target.chunk),
Steps.Features);
} finally {
target.releaseOwnerLock();
}
}
}
}
}
r.run();
return referencedChunks;
}
enum Steps {
Empty, StructureStart, StructureReference, Biomes, Noise, Surface, Carvers, LiquidCarvers, Features, Light,
}
public static class StepStructureStart {
public static final ChunkStatus STATUS = ChunkStatus.STRUCTURE_STARTS;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
private static ChunkGenerator gen;
private static boolean doGenerateFeatures = true;
private static RegistryAccess registry;
private static StructureFeatureManager structFeat;
private static StructureManager struct;
private static long seed;
public final static void onLevelLoad(ChunkGenerator generator, WorldGenSettings genSettings, RegistryAccess registryAccess,
StructureFeatureManager structureFeature, StructureManager structures, long worldSeed) {
gen = generator;
doGenerateFeatures = genSettings.generateFeatures();
registry = registryAccess;
structFeat = structureFeature;
struct = structures;
seed = worldSeed;
}
public final static ChunkAccess generate(ChunkAccess chunk) {
if (doGenerateFeatures) {
// Should be thread safe
gen.createStructures(registry, structFeat, chunk, struct, seed);
}
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
static ChunkAccess load(ServerLevel level, ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
}
public static class StepStructureReference {
public static final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
private static ChunkGenerator gen;
private static StructureFeatureManager structFeat;
private static ServerLevel level;
public final static void onLevelLoad(ServerLevel serverLevel, ChunkGenerator generator, StructureFeatureManager structureFeature) {
gen = generator;
structFeat = structureFeature;
level = serverLevel;
}
public static final void generate(List<ChunkAccess> chunkList, ChunkAccess chunk) {
WorldGenRegion worldGenRegion = new WorldGenRegion(level, chunkList, STATUS, -1);
// Note: Not certain StructureFeatureManager.forWorldGenRegion(...) is thread safe
gen.createReferences(worldGenRegion, structFeat.forWorldGenRegion(worldGenRegion), chunk);
((ProtoChunk) chunk).setStatus(STATUS);
}
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
}
public static class StepBiomes {
public static final ChunkStatus STATUS = ChunkStatus.BIOMES;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public static Registry<Biome> biomeRegistry;
private static ChunkGenerator gen;
private static StructureFeatureManager structFeat;
private static ServerLevel level;
public final static void onLevelLoad(ServerLevel serverLevel, ChunkGenerator generator, Registry<Biome> registry, StructureFeatureManager structureFeature) {
biomeRegistry = registry;
gen = generator;
structFeat = structureFeature;
level = serverLevel;
}
public static final ChunkAccess generate(List<ChunkAccess> chunkList, ChunkAccess chunk, Executor worker) {
WorldGenRegion worldGenRegion = new WorldGenRegion(level, chunkList, STATUS, -1);
chunk = joinAsync(gen.fillFromNoise(worker, structFeat.forWorldGenRegion(worldGenRegion), chunk));
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
}
public static class StepNoise {
public static final ChunkStatus STATUS = ChunkStatus.NOISE;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
private static ChunkGenerator gen;
private static StructureFeatureManager structFeat;
private static ServerLevel level;
public final static void onLevelLoad(ServerLevel serverLevel, ChunkGenerator generator, StructureFeatureManager structureFeature) {
gen = generator;
structFeat = structureFeature;
level = serverLevel;
}
public static final ChunkAccess generate(List<ChunkAccess> chunkList, ChunkAccess chunk, Executor worker) {
WorldGenRegion worldGenRegion = new WorldGenRegion(level, chunkList, STATUS, 0);
chunk = joinAsync(gen.fillFromNoise(worker, structFeat.forWorldGenRegion(worldGenRegion), chunk));
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
}
public static class StepSurface {
public static final ChunkStatus STATUS = ChunkStatus.SURFACE;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
private static ChunkGenerator gen;
private static StructureFeatureManager structFeat;
private static ServerLevel level;
public final static void onLevelLoad(ServerLevel serverLevel, ChunkGenerator generator, StructureFeatureManager structureFeature) {
gen = generator;
structFeat = structureFeature;
level = serverLevel;
}
public static final ChunkAccess generate(List<ChunkAccess> chunkList, ChunkAccess chunk) {
WorldGenRegion worldGenRegion = new WorldGenRegion(level, chunkList, STATUS, 0);
gen.buildSurfaceAndBedrock(worldGenRegion, chunk);
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
}
public static class StepCarvers {
public static final ChunkStatus STATUS = ChunkStatus.CARVERS;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
private static ChunkGenerator gen;
private static StructureFeatureManager structFeat;
private static ServerLevel level;
private static long seed;
private static BiomeManager biomes;
public final static void onLevelLoad(ServerLevel serverLevel, ChunkGenerator generator, StructureFeatureManager structureFeature,
long worldSeed, BiomeManager biomeManger) {
gen = generator;
structFeat = structureFeature;
level = serverLevel;
seed = worldSeed;
biomes = biomeManger;
}
public static final ChunkAccess generate(List<ChunkAccess> chunkList, ChunkAccess chunk) {
gen.applyCarvers(seed, biomes, chunk, GenerationStep.Carving.AIR);
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
}
public static class StepLiquidCarvers {
public static final ChunkStatus STATUS = ChunkStatus.LIQUID_CARVERS;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
public static final ChunkAccess generate(List<ChunkAccess> chunkList, ChunkAccess chunk, Executor worker) {
// FIXME: I think the decompiler failed on this one. Find the actual body and
// put it here.
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
}
public static class StepFeatures {
public static final ChunkStatus STATUS = ChunkStatus.FEATURES;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
private static ChunkGenerator gen;
private static StructureFeatureManager structFeat;
private static ServerLevel level;
private static LevelLightEngine lights;
public final static void onLevelLoad(ServerLevel serverLevel, ChunkGenerator generator, StructureFeatureManager structureFeature,
LevelLightEngine lightEngine) {
gen = generator;
structFeat = structureFeature;
level = serverLevel;
lights = lightEngine;
}
private static ReentrantLock testLock = new ReentrantLock();
public static final ChunkAccess generate(List<ChunkAccess> chunkList, ChunkAccess chunk) {
ProtoChunk protoChunk = (ProtoChunk) chunk;
if (chunk.getStatus() == STATUS) return chunk;
testLock.lock();
try {
if (chunk.getStatus() != STATUS) {
protoChunk.setLightEngine(lights);
Heightmap.primeHeightmaps(chunk,
EnumSet.of(Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES,
Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE));
// This could be problematic. May need to lock the 8 surrounding chunks then.
WorldGenRegion worldGenRegion = new WorldGenRegion(level, chunkList, STATUS, 1);
gen.applyBiomeDecoration(worldGenRegion, structFeat.forWorldGenRegion(worldGenRegion));
//Blender.generateBorderTicks(worldGenRegion, chunk);
protoChunk.setStatus(STATUS);
}
} finally {
testLock.unlock();
}
return chunk;
}
static ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return chunk;
}
}
public static class StepLight {
public static final ChunkStatus STATUS = ChunkStatus.LIGHT;
public static final int RANGE = STATUS.getRange();
public static final EnumSet<Heightmap.Types> HEIGHTMAP_TYPES = STATUS.heightmapsAfter();
private static ThreadedLevelLightEngine lightEngine;
public final static void onLevelLoad(ThreadedLevelLightEngine engine) {
lightEngine = engine;
}
public static final ChunkAccess generate(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return joinAsync(lightEngine.lightChunk(chunk, chunk.isLightCorrect()));
}
public static final ChunkAccess load(ChunkAccess chunk) {
((ProtoChunk) chunk).setStatus(STATUS);
return joinAsync(lightEngine.lightChunk(chunk, chunk.isLightCorrect()));
}
}
// The following may not be needed
/*
* public static class Spawn implements SimpleGen {
*
* @Override public EnumSet<Types> getHeightmapTypes() { return POST_FEATURES; }
*
* @Override public int getDependencyRange() { return 0; }
*
* @Override public final void doSimpleWork(ChunkStatus targetStatus,
* ServerLevel level, ChunkGenerator generator, List<ChunkAccess> chunkList,
* ChunkAccess chunk) { if (!chunk.isUpgrading())
* generator.spawnOriginalMobs(new WorldGenRegion(level, chunkList,
* targetStatus, -1)); } } public static class Heightmaps implements SimpleGen {
*
* @Override public EnumSet<Types> getHeightmapTypes() { return POST_FEATURES; }
*
* @Override public int getDependencyRange() { return 0; }
*
* @Override public final void doSimpleWork(ChunkStatus targetStatus,
* ServerLevel level, ChunkGenerator generator, List<ChunkAccess> chunkList,
* ChunkAccess chunk) { // Apearently nothing again??? Decompiler Error? } }
*
* public static class Full implements Gen {
*
* @Override public EnumSet<Types> getHeightmapTypes() { return POST_FEATURES; }
*
* @Override public int getDependencyRange() { return 0; }
*
* @Override public final ChunkAccess doWork(ChunkStatus targetStatus, Executor
* worker, ServerLevel level, ChunkGenerator generator, StructureManager
* structures, ThreadedLevelLightEngine lightEngine, Mutator function,
* List<ChunkAccess> chunkList, ChunkAccess chunk, boolean alwaysRegenerate) {
* return function.call(chunk); }
*
* @Override public final ChunkAccess load(ChunkStatus targetStatus, ServerLevel
* level, StructureManager structures, ThreadedLevelLightEngine lightEngine,
* Mutator function, ChunkAccess chunk) { return function.call(chunk); } }
*
*
*/
}
@@ -63,4 +63,11 @@ public class Main implements ClientModInitializer
client_proxy = new ClientProxy();
client_proxy.registerEvents();
}
public static void initServer() {
LodCommonMain.initConfig();
LodCommonMain.startup(null, true);
DependencySetup.createInitialBindings();
ClientApi.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
}
}
+3 -3
View File
@@ -4,15 +4,15 @@
"package": "com.seibel.lod.fabric.mixins",
"compatibilityLevel": "JAVA_16",
"mixins": [
"unsafe.MixinPalettedContainer"
"unsafe.MixinPalettedContainer",
"events.MixinServerLevel"
],
"client": [
"MixinMinecraft",
"MixinOptionsScreen",
"MixinWorldRenderer",
"events.MixinClientLevel",
"events.MixinMinecraft",
"events.MixinServerLevel"
"events.MixinMinecraft"
],
"server": [],
"injectors": {
@@ -64,6 +64,7 @@ public class ForgeMain implements LodForgeMethodCaller
private void init(final FMLCommonSetupEvent event)
{
// make sure the dependencies are set up before the mod needs them
LodCommonMain.initConfig();
LodCommonMain.startup(this, !FMLLoader.getDist().isClient());
ForgeDependencySetup.createInitialBindings();
}
@@ -83,7 +84,6 @@ public class ForgeMain implements LodForgeMethodCaller
{
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> Config.getScreen(parent, ModInfo.ID, "")));
LodCommonMain.initConfig();
forgeClientProxy = new ForgeClientProxy();
MinecraftForge.EVENT_BUS.register(forgeClientProxy);
}
@@ -0,0 +1,13 @@
package com.seibel.lod.forge.wrappers.config;
import com.seibel.lod.common.Config;
import com.seibel.lod.core.ModInfo;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fmlclient.ConfigGuiHandler;
public class MenuIntegration {
public static void registerModsPage() {
ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class,
() -> new ConfigGuiHandler.ConfigGuiFactory((client, parent) -> Config.getScreen(parent, ModInfo.ID, "")));
}
}
+2 -1
View File
@@ -3,9 +3,10 @@
"package": "com.seibel.lod.forge.mixins",
"compatibilityLevel": "JAVA_16",
"refmap": "lod.refmap.json",
"mixins": [
"client": [
"MixinWorldRenderer",
"MixinOptionsScreen"
],
"mixins": [],
"minVersion": "0.8"
}