Start creating API classes, some general refactoring/reorganizing, and wrapper changes
This commit is contained in:
+6
-10
@@ -33,8 +33,7 @@ import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
|
||||
/**
|
||||
* Initialize and setup the Mod.
|
||||
* <br>
|
||||
* Initialize and setup the Mod. <br>
|
||||
* If you are looking for the real start of the mod
|
||||
* check out the ClientProxy.
|
||||
*
|
||||
@@ -42,12 +41,9 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
* @version 7-3-2021
|
||||
*/
|
||||
@Mod(ModInfo.ID)
|
||||
public class LodMain
|
||||
public class LodForgeMain
|
||||
{
|
||||
public static LodMain instance;
|
||||
|
||||
public static ClientProxy client_proxy;
|
||||
|
||||
public static ClientProxy clientProxy;
|
||||
|
||||
private void init(final FMLCommonSetupEvent event)
|
||||
{
|
||||
@@ -55,7 +51,7 @@ public class LodMain
|
||||
}
|
||||
|
||||
|
||||
public LodMain()
|
||||
public LodForgeMain()
|
||||
{
|
||||
// Register the methods
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init);
|
||||
@@ -67,8 +63,8 @@ public class LodMain
|
||||
|
||||
private void onClientStart(final FMLClientSetupEvent event)
|
||||
{
|
||||
client_proxy = new ClientProxy();
|
||||
MinecraftForge.EVENT_BUS.register(client_proxy);
|
||||
clientProxy = new ClientProxy();
|
||||
MinecraftForge.EVENT_BUS.register(clientProxy);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.seibel.lod.api;
|
||||
|
||||
import com.seibel.lod.LodMain;
|
||||
import com.seibel.lod.objects.rending.Mat4f;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-11-2021
|
||||
*/
|
||||
public class ClientApi
|
||||
{
|
||||
|
||||
public ClientApi()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void renderLods(Mat4f mcModelViewMatrix, float partialTicks)
|
||||
{
|
||||
LodMain.client_proxy.renderLods(mcModelViewMatrix, partialTicks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -39,14 +39,14 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.lod.builders.bufferBuilding.lodTemplates.Box;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.GlProxyContext;
|
||||
import com.seibel.lod.enums.GpuUploadMethod;
|
||||
import com.seibel.lod.enums.VanillaOverdraw;
|
||||
import com.seibel.lod.enums.config.GpuUploadMethod;
|
||||
import com.seibel.lod.enums.config.VanillaOverdraw;
|
||||
import com.seibel.lod.enums.rendering.GlProxyContext;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.objects.PosToRenderContainer;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.objects.lod.LodRegion;
|
||||
import com.seibel.lod.objects.lod.RegionPos;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.proxy.GlProxy;
|
||||
import com.seibel.lod.render.LodRenderer;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
@@ -229,7 +229,7 @@ public class LodBufferBuilder
|
||||
// create the nodeToRenderThreads //
|
||||
//================================//
|
||||
|
||||
skyLightPlayer = MinecraftWrapper.INSTANCE.getWrappedClientLevel().getSkyLight(playerBlockPos);
|
||||
skyLightPlayer = MinecraftWrapper.INSTANCE.getWrappedClientWorld().getSkyLight(playerBlockPos);
|
||||
|
||||
for (int xRegion = 0; xRegion < lodDim.getWidth(); xRegion++)
|
||||
{
|
||||
@@ -426,7 +426,7 @@ public class LodBufferBuilder
|
||||
// the future will be false if its thread failed
|
||||
if (!future.get())
|
||||
{
|
||||
ClientProxy.LOGGER.warn("LodBufferBuilder ran into trouble and had to start over.");
|
||||
ClientApi.LOGGER.warn("LodBufferBuilder ran into trouble and had to start over.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -445,7 +445,7 @@ public class LodBufferBuilder
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ClientProxy.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" ran into trouble: ");
|
||||
ClientApi.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" ran into trouble: ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
@@ -461,7 +461,7 @@ public class LodBufferBuilder
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ClientProxy.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" was unable to upload the buffers to the GPU: " + e.getMessage());
|
||||
ClientApi.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" was unable to upload the buffers to the GPU: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -792,7 +792,7 @@ public class LodBufferBuilder
|
||||
catch (Exception e)
|
||||
{
|
||||
// this doesn't appear to be necessary anymore, but just in case.
|
||||
ClientProxy.LOGGER.error(LodBufferBuilder.class.getSimpleName() + " - UploadBuffers failed: " + e.getMessage());
|
||||
ClientApi.LOGGER.error(LodBufferBuilder.class.getSimpleName() + " - UploadBuffers failed: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
@@ -911,7 +911,7 @@ public class LodBufferBuilder
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ClientProxy.LOGGER.error("vboUpload failed: " + e.getClass().getSimpleName());
|
||||
ClientApi.LOGGER.error("vboUpload failed: " + e.getClass().getSimpleName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ package com.seibel.lod.builders.bufferBuilding.lodTemplates;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.seibel.lod.enums.DebugMode;
|
||||
import com.seibel.lod.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.util.ColorUtil;
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DebugMode;
|
||||
import com.seibel.lod.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.util.ColorUtil;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
@@ -249,7 +249,7 @@ public class Box
|
||||
for (Direction direction : DIRECTIONS)
|
||||
{
|
||||
if (!adjShadeDisabled[DIRECTION_INDEX.get(direction)])
|
||||
colorMap[DIRECTION_INDEX.get(direction)] = ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getClientLevel().getShade(direction, true));
|
||||
colorMap[DIRECTION_INDEX.get(direction)] = ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getClientWorld().getShade(direction, true));
|
||||
else
|
||||
colorMap[DIRECTION_INDEX.get(direction)] = color;
|
||||
}
|
||||
@@ -264,7 +264,7 @@ public class Box
|
||||
if (LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get() != DebugMode.SHOW_DETAIL)
|
||||
return colorMap[DIRECTION_INDEX.get(direction)];
|
||||
else
|
||||
return ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getClientLevel().getShade(direction, true));
|
||||
return ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getClientWorld().getShade(direction, true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ package com.seibel.lod.builders.bufferBuilding.lodTemplates;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.seibel.lod.enums.DebugMode;
|
||||
import com.seibel.lod.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.util.ColorUtil;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
+3
-4
@@ -21,9 +21,8 @@ package com.seibel.lod.builders.bufferBuilding.lodTemplates;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.seibel.lod.enums.DebugMode;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
|
||||
import com.seibel.lod.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.util.Direction;
|
||||
@@ -42,7 +41,7 @@ public class DynamicLodTemplate extends AbstractLodTemplate
|
||||
public void addLodToBuffer(BufferBuilder buffer, BlockPosWrapper bufferCenterBlockPos, long data, Map<Direction, long[]> adjData,
|
||||
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled)
|
||||
{
|
||||
ClientProxy.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!");
|
||||
ClientApi.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-4
@@ -21,9 +21,8 @@ package com.seibel.lod.builders.bufferBuilding.lodTemplates;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.seibel.lod.enums.DebugMode;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
|
||||
import com.seibel.lod.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.util.Direction;
|
||||
@@ -40,7 +39,7 @@ public class TriangularLodTemplate extends AbstractLodTemplate
|
||||
public void addLodToBuffer(BufferBuilder buffer, BlockPosWrapper bufferCenterBlockPos, long data, Map<Direction, long[]> adjData,
|
||||
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled)
|
||||
{
|
||||
ClientProxy.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!");
|
||||
ClientApi.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.HorizontalResolution;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.HorizontalResolution;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.objects.lod.LodRegion;
|
||||
import com.seibel.lod.objects.lod.LodWorld;
|
||||
@@ -42,10 +42,8 @@ import com.seibel.lod.wrappers.Block.BlockShapeWrapper;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkWrapper;
|
||||
import com.seibel.lod.wrappers.World.BiomeWrapper;
|
||||
import com.seibel.lod.wrappers.World.LevelWrapper;
|
||||
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.IWorld;
|
||||
import com.seibel.lod.wrappers.World.DimensionTypeWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
|
||||
/**
|
||||
* This object is in charge of creating Lod related objects.
|
||||
@@ -86,12 +84,12 @@ public class LodBuilder
|
||||
|
||||
}
|
||||
|
||||
public void generateLodNodeAsync(ChunkWrapper chunk, LodWorld lodWorld, IWorld world)
|
||||
public void generateLodNodeAsync(ChunkWrapper chunk, LodWorld lodWorld, DimensionTypeWrapper dim)
|
||||
{
|
||||
generateLodNodeAsync(chunk, lodWorld, world, DistanceGenerationMode.SERVER);
|
||||
generateLodNodeAsync(chunk, lodWorld, dim, DistanceGenerationMode.SERVER);
|
||||
}
|
||||
|
||||
public void generateLodNodeAsync(ChunkWrapper chunk, LodWorld lodWorld, IWorld world, DistanceGenerationMode generationMode)
|
||||
public void generateLodNodeAsync(ChunkWrapper chunk, LodWorld lodWorld, DimensionTypeWrapper dim, DistanceGenerationMode generationMode)
|
||||
{
|
||||
if (lodWorld == null || lodWorld.getIsWorldNotLoaded())
|
||||
return;
|
||||
@@ -108,7 +106,7 @@ public class LodBuilder
|
||||
{
|
||||
// we need a loaded client world in order to
|
||||
// get the textures for blocks
|
||||
if (mc.getClientLevel() == null)
|
||||
if (mc.getClientWorld() == null)
|
||||
return;
|
||||
|
||||
// don't try to generate LODs if the user isn't in the world anymore
|
||||
@@ -116,8 +114,6 @@ public class LodBuilder
|
||||
if (mc.getSinglePlayerServer() == null && mc.getCurrentServer() == null)
|
||||
return;
|
||||
|
||||
DimensionType dim = world.dimensionType();
|
||||
|
||||
// make sure the dimension exists
|
||||
LodDimension lodDim;
|
||||
if (lodWorld.getLodDimension(dim) == null)
|
||||
@@ -170,7 +166,7 @@ public class LodBuilder
|
||||
return;
|
||||
|
||||
// this happens if a LOD is generated after the user leaves the world.
|
||||
if (MinecraftWrapper.INSTANCE.getWrappedClientLevel() == null)
|
||||
if (MinecraftWrapper.INSTANCE.getWrappedClientWorld() == null)
|
||||
return;
|
||||
|
||||
// determine how many LODs to generate horizontally
|
||||
@@ -230,8 +226,8 @@ public class LodBuilder
|
||||
int xAbs;
|
||||
int yAbs;
|
||||
int zAbs;
|
||||
boolean hasCeiling = mc.getClientLevel().dimensionType().hasCeiling();
|
||||
boolean hasSkyLight = mc.getClientLevel().dimensionType().hasSkyLight();
|
||||
boolean hasCeiling = mc.getClientWorld().dimensionType().hasCeiling();
|
||||
boolean hasSkyLight = mc.getClientWorld().dimensionType().hasSkyLight();
|
||||
boolean isDefault;
|
||||
BlockPosWrapper blockPos = new BlockPosWrapper();
|
||||
int index;
|
||||
@@ -386,7 +382,7 @@ public class LodBuilder
|
||||
// 1 means the lighting is a guess
|
||||
int isDefault = 0;
|
||||
|
||||
LevelWrapper world = MinecraftWrapper.INSTANCE.getWrappedServerLevel();
|
||||
WorldWrapper world = MinecraftWrapper.INSTANCE.getWrappedServerWorld();
|
||||
|
||||
int blockBrightness = chunk.getEmittedBrightness(blockPos);
|
||||
// get the air block above or below this block
|
||||
@@ -414,7 +410,7 @@ public class LodBuilder
|
||||
{
|
||||
// we are on predicted terrain, and we don't know what the light here is,
|
||||
// lets just take a guess
|
||||
if (blockPos.getY() >= mc.getClientLevel().getSeaLevel() - 5)
|
||||
if (blockPos.getY() >= mc.getClientWorld().getSeaLevel() - 5)
|
||||
{
|
||||
skyLight = 12;
|
||||
isDefault = 1;
|
||||
@@ -425,7 +421,7 @@ public class LodBuilder
|
||||
}
|
||||
else
|
||||
{
|
||||
world = MinecraftWrapper.INSTANCE.getWrappedClientLevel();
|
||||
world = MinecraftWrapper.INSTANCE.getWrappedServerWorld();
|
||||
if (world.isEmpty())
|
||||
return 0;
|
||||
// client world sky light (almost never accurate)
|
||||
@@ -447,7 +443,7 @@ public class LodBuilder
|
||||
{
|
||||
// we don't know what the light here is,
|
||||
// lets just take a guess
|
||||
if (blockPos.getY() >= mc.getClientLevel().getSeaLevel() - 5)
|
||||
if (blockPos.getY() >= mc.getClientWorld().getSeaLevel() - 5)
|
||||
{
|
||||
skyLight = 12;
|
||||
isDefault = 1;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
package com.seibel.lod.builders.lodBuilding;
|
||||
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
|
||||
/**
|
||||
* This is used to easily configure how LodChunks are generated.
|
||||
|
||||
@@ -32,13 +32,13 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.seibel.lod.builders.lodBuilding.LodBuilder;
|
||||
import com.seibel.lod.builders.lodBuilding.LodBuilderConfig;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.palette.UpgradeData;
|
||||
@@ -92,7 +92,7 @@ public class LodGenWorker implements IWorker
|
||||
|
||||
public LodGenWorker(ChunkPosWrapper newPos, DistanceGenerationMode newGenerationMode,
|
||||
LodBuilder newLodBuilder,
|
||||
LodDimension newLodDimension, ServerWorld newServerWorld)
|
||||
LodDimension newLodDimension, WorldWrapper serverWorld)
|
||||
{
|
||||
// just a few sanity checks
|
||||
if (newPos == null)
|
||||
@@ -104,14 +104,14 @@ public class LodGenWorker implements IWorker
|
||||
if (newLodDimension == null)
|
||||
throw new IllegalArgumentException("LodChunkGenThread requires a non-null LodDimension");
|
||||
|
||||
if (newServerWorld == null)
|
||||
if (serverWorld == null)
|
||||
throw new IllegalArgumentException("LodChunkGenThread requires a non-null ServerWorld");
|
||||
|
||||
|
||||
|
||||
thread = new LodChunkGenThread(newPos, newGenerationMode,
|
||||
newLodBuilder,
|
||||
newLodDimension, newServerWorld);
|
||||
newLodDimension, serverWorld.getServerWorld()); // TODO wrapper needed
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.seibel.lod.builders.lodBuilding.LodBuilder;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.objects.PosToGenerateContainer;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.render.LodRenderer;
|
||||
@@ -35,10 +35,10 @@ import com.seibel.lod.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.util.LevelPosUtil;
|
||||
import com.seibel.lod.util.LodThreadFactory;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.WorldWorkerManager;
|
||||
|
||||
/**
|
||||
@@ -115,7 +115,7 @@ public class LodWorldGenerator
|
||||
// fill in positionsWaitingToBeGenerated //
|
||||
//=======================================//
|
||||
|
||||
ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(lodDim.dimension);
|
||||
WorldWrapper serverWorld = LodUtil.getServerWorldFromDimension(lodDim.dimension);
|
||||
|
||||
PosToGenerateContainer posToGenerate = lodDim.getPosToGenerate(
|
||||
maxChunkGenRequests,
|
||||
|
||||
@@ -28,20 +28,20 @@ import org.apache.logging.log4j.LogManager;
|
||||
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
import com.electronwill.nightconfig.core.io.WritingMode;
|
||||
import com.seibel.lod.ModInfo;
|
||||
import com.seibel.lod.enums.BlockToAvoid;
|
||||
import com.seibel.lod.enums.BufferRebuildTimes;
|
||||
import com.seibel.lod.enums.DebugMode;
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.FogDistance;
|
||||
import com.seibel.lod.enums.FogDrawOverride;
|
||||
import com.seibel.lod.enums.GenerationPriority;
|
||||
import com.seibel.lod.enums.GpuUploadMethod;
|
||||
import com.seibel.lod.enums.HorizontalQuality;
|
||||
import com.seibel.lod.enums.HorizontalResolution;
|
||||
import com.seibel.lod.enums.HorizontalScale;
|
||||
import com.seibel.lod.enums.LodTemplate;
|
||||
import com.seibel.lod.enums.VanillaOverdraw;
|
||||
import com.seibel.lod.enums.VerticalQuality;
|
||||
import com.seibel.lod.enums.config.BlockToAvoid;
|
||||
import com.seibel.lod.enums.config.BufferRebuildTimes;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.GenerationPriority;
|
||||
import com.seibel.lod.enums.config.GpuUploadMethod;
|
||||
import com.seibel.lod.enums.config.HorizontalQuality;
|
||||
import com.seibel.lod.enums.config.HorizontalResolution;
|
||||
import com.seibel.lod.enums.config.HorizontalScale;
|
||||
import com.seibel.lod.enums.config.LodTemplate;
|
||||
import com.seibel.lod.enums.config.VanillaOverdraw;
|
||||
import com.seibel.lod.enums.config.VerticalQuality;
|
||||
import com.seibel.lod.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.enums.rendering.FogDistance;
|
||||
import com.seibel.lod.enums.rendering.FogDrawOverride;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
|
||||
/**
|
||||
* ServerWorld, ClientWorld, Unknown
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public enum WorldType
|
||||
{
|
||||
ServerWorld,
|
||||
ClientWorld,
|
||||
Unknown
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* heightmap <br>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* Near_First <br>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* NONE <br>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* Near_First <br>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* Buffer_Storage, Sub_Data, Buffer_Mapping
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* Lowest <br>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* Low <br>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
import com.seibel.lod.builders.bufferBuilding.lodTemplates.AbstractLodTemplate;
|
||||
import com.seibel.lod.builders.bufferBuilding.lodTemplates.CubicLodTemplate;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* NONE, GAME_SHADING
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* None, Dynamic, Always
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.config;
|
||||
|
||||
/**
|
||||
* heightmap <br>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.rendering;
|
||||
|
||||
/**
|
||||
* off, detail, detail wireframe
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.rendering;
|
||||
|
||||
/**
|
||||
* NEAR, FAR, or NEAR_AND_FAR.
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.rendering;
|
||||
|
||||
/**
|
||||
* USE_OPTIFINE_FOG_SETTING, <br>
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.rendering;
|
||||
|
||||
/**
|
||||
* fast, fancy, or off
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.enums;
|
||||
package com.seibel.lod.enums.rendering;
|
||||
|
||||
/**
|
||||
* Minecraft, Lod_Builder, None
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.handlers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Cola
|
||||
* @author Leonardo Amato
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public class ChunkFileLoader
|
||||
{
|
||||
// TODO
|
||||
// public static IChunk getChunkFromFile(ChunkPos pos)
|
||||
// {
|
||||
// LevelWrapper clientLevel = MinecraftWrapper.INSTANCE.getWrappedClientLevel();
|
||||
// if (clientLevel == null)
|
||||
// return null;
|
||||
// WorldWrapper serverWorld = LodUtil.getServerWorldFromDimension(clientLevel.getDimensionType());
|
||||
// try
|
||||
// {
|
||||
// File file = new File(serverWorld.getSaveFolder().getParent() + File.separatorChar + "region", "r." + (pos.x >> 5) + "." + (pos.z >> 5) + ".mca");
|
||||
// if(!file.exists())
|
||||
// return null;
|
||||
// IChunk loadedChunk = ChunkSerializer.read(
|
||||
// serverWorld,
|
||||
// serverWorld.getStructureManager(),
|
||||
// serverWorld.getPoiManager(),
|
||||
// pos,
|
||||
// serverWorld.getChunkSource().chunkMap.read(pos)
|
||||
// );
|
||||
// boolean emptyChunk = true;
|
||||
// for(int i = 0; i < 16; i++){
|
||||
// for(int j = 0; j < 16; j++){
|
||||
// emptyChunk &= loadedChunk.isYSpaceEmpty(i,j);
|
||||
// }
|
||||
// }
|
||||
// if(emptyChunk)
|
||||
// return null;
|
||||
// else
|
||||
// return loadedChunk;
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.handlers;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
|
||||
import com.seibel.lod.wrappers.World.LevelWrapper;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
import net.minecraft.world.chunk.storage.ChunkSerializer;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author ??
|
||||
* @version ??
|
||||
*/
|
||||
public class ChunkLoader
|
||||
{
|
||||
public static IChunk getChunkFromFile(ChunkPos pos){
|
||||
|
||||
LevelWrapper clientLevel = MinecraftWrapper.INSTANCE.getWrappedClientLevel();
|
||||
if (clientLevel == null)
|
||||
return null;
|
||||
ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(clientLevel.getWorld().dimensionType());
|
||||
try
|
||||
{
|
||||
File file = new File(serverWorld.getChunkSource().getDataStorage().dataFolder.getParent() + File.separatorChar + "region", "r." + (pos.x >> 5) + "." + (pos.z >> 5) + ".mca");
|
||||
if(!file.exists())
|
||||
return null;
|
||||
IChunk loadedChunk = ChunkSerializer.read(
|
||||
serverWorld,
|
||||
serverWorld.getStructureManager(),
|
||||
serverWorld.getPoiManager(),
|
||||
pos,
|
||||
serverWorld.getChunkSource().chunkMap.read(pos)
|
||||
);
|
||||
boolean emptyChunk = true;
|
||||
for(int i = 0; i < 16; i++){
|
||||
for(int j = 0; j < 16; j++){
|
||||
emptyChunk &= loadedChunk.isYSpaceEmpty(i,j);
|
||||
}
|
||||
}
|
||||
if(emptyChunk)
|
||||
return null;
|
||||
else
|
||||
return loadedChunk;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,13 +29,13 @@ import java.util.concurrent.Executors;
|
||||
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
|
||||
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.VerticalQuality;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.VerticalQuality;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.objects.lod.LodRegion;
|
||||
import com.seibel.lod.objects.lod.RegionPos;
|
||||
import com.seibel.lod.objects.lod.VerticalLevelContainer;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.util.LodThreadFactory;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.util.ThreadMapUtil;
|
||||
@@ -175,7 +175,7 @@ public class LodDimensionFileHandler
|
||||
// close the reader and delete the file.
|
||||
inputStream.close();
|
||||
file.delete();
|
||||
ClientProxy.LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ")"
|
||||
ClientApi.LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ")"
|
||||
+ " version found: " + fileVersion
|
||||
+ ", version requested: " + LOD_SAVE_FILE_VERSION
|
||||
+ ". File was been deleted.");
|
||||
@@ -188,7 +188,7 @@ public class LodDimensionFileHandler
|
||||
// close the reader and ignore the file, we don't
|
||||
// want to accidentally delete anything the user may want.
|
||||
inputStream.close();
|
||||
ClientProxy.LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ")"
|
||||
ClientApi.LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ")"
|
||||
+ " version found: " + fileVersion
|
||||
+ ", version requested: " + LOD_SAVE_FILE_VERSION
|
||||
+ " this region will not be written to in order to protect the newer file.");
|
||||
@@ -209,7 +209,7 @@ public class LodDimensionFileHandler
|
||||
}
|
||||
catch (IOException ioEx)
|
||||
{
|
||||
ClientProxy.LOGGER.error("LOD file read error. Unable to read to [" + fileName + "] error [" + ioEx.getMessage() + "]: ");
|
||||
ClientApi.LOGGER.error("LOD file read error. Unable to read to [" + fileName + "] error [" + ioEx.getMessage() + "]: ");
|
||||
ioEx.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -218,7 +218,7 @@ public class LodDimensionFileHandler
|
||||
{
|
||||
// the buffered reader encountered a
|
||||
// problem reading the file
|
||||
ClientProxy.LOGGER.error("LOD file read error. Unable to read to [" + fileName + "] error [" + e.getMessage() + "]: ");
|
||||
ClientApi.LOGGER.error("LOD file read error. Unable to read to [" + fileName + "] error [" + e.getMessage() + "]: ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}// for each detail level
|
||||
@@ -280,7 +280,7 @@ public class LodDimensionFileHandler
|
||||
// for some reason
|
||||
if (fileName == null)
|
||||
{
|
||||
ClientProxy.LOGGER.warn("Unable to save region [" + region.regionPosX + ", " + region.regionPosZ + "] to file, file is inaccessible.");
|
||||
ClientApi.LOGGER.warn("Unable to save region [" + region.regionPosX + ", " + region.regionPosZ + "] to file, file is inaccessible.");
|
||||
return;
|
||||
}
|
||||
File oldFile = new File(fileName);
|
||||
@@ -331,7 +331,7 @@ public class LodDimensionFileHandler
|
||||
// existing file is complete while new one is only partially generate
|
||||
// this can happen is for some reason loading failed
|
||||
// this doesn't fix the bug, but at least protects old data
|
||||
ClientProxy.LOGGER.error("LOD file write error. Attempted to overwrite complete region with incomplete one [" + fileName + "]");
|
||||
ClientApi.LOGGER.error("LOD file write error. Attempted to overwrite complete region with incomplete one [" + fileName + "]");
|
||||
return;
|
||||
}
|
||||
// if we got this far then we are good
|
||||
@@ -358,7 +358,7 @@ public class LodDimensionFileHandler
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ClientProxy.LOGGER.error("LOD file write error. Unable to write to [" + fileName + "] error [" + e.getMessage() + "]: ");
|
||||
ClientApi.LOGGER.error("LOD file write error. Unable to write to [" + fileName + "] error [" + e.getMessage() + "]: ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -382,7 +382,7 @@ public class LodDimensionFileHandler
|
||||
}
|
||||
catch (IOException ioEx)
|
||||
{
|
||||
ClientProxy.LOGGER.error("LOD file read error. Unable to read to [" + fileName + "] error [" + ioEx.getMessage() + "]: ");
|
||||
ClientApi.LOGGER.error("LOD file read error. Unable to read to [" + fileName + "] error [" + ioEx.getMessage() + "]: ");
|
||||
ioEx.printStackTrace();
|
||||
}
|
||||
return new byte[0];
|
||||
@@ -414,7 +414,7 @@ public class LodDimensionFileHandler
|
||||
}
|
||||
catch (IOException | SecurityException e)
|
||||
{
|
||||
ClientProxy.LOGGER.warn("Unable to get the filename for the region [" + regionX + ", " + regionZ + "], error: [" + e.getMessage() + "], stacktrace: ");
|
||||
ClientApi.LOGGER.warn("Unable to get the filename for the region [" + regionX + ", " + regionZ + "], error: [" + e.getMessage() + "], stacktrace: ");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
package com.seibel.lod.handlers;
|
||||
|
||||
import com.seibel.lod.enums.FogQuality;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.enums.rendering.FogQuality;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
||||
@@ -70,7 +70,7 @@ public class ReflectionHandler
|
||||
// we didn't find the field,
|
||||
// either optifine isn't installed, or
|
||||
// optifine changed the name of the variable
|
||||
ClientProxy.LOGGER.info(ReflectionHandler.class.getSimpleName() + ": unable to find the Optifine fog field. If Optifine isn't installed this can be ignored.");
|
||||
ClientApi.LOGGER.info(ReflectionHandler.class.getSimpleName() + ": unable to find the Optifine fog field. If Optifine isn't installed this can be ignored.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.lodApi;
|
||||
|
||||
import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder;
|
||||
import com.seibel.lod.builders.lodBuilding.LodBuilder;
|
||||
import com.seibel.lod.objects.lod.LodWorld;
|
||||
|
||||
/**
|
||||
* This stores objects and variables that
|
||||
* are shared between the different LodApi classes.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public class ApiShared
|
||||
{
|
||||
public ApiShared INSTANCE = new ApiShared();
|
||||
|
||||
public static final LodBufferBuilder lodBufferBuilder = new LodBufferBuilder();
|
||||
public static final LodWorld lodWorld = new LodWorld();
|
||||
public static final LodBuilder lodBuilder = new LodBuilder();
|
||||
|
||||
/** Used to determine if the LODs should be regenerated */
|
||||
public static int previousChunkRenderDistance = 0;
|
||||
/** Used to determine if the LODs should be regenerated */
|
||||
public static int previousLodRenderDistance = 0;
|
||||
|
||||
|
||||
|
||||
private ApiShared()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.lodApi;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.seibel.lod.builders.worldGeneration.LodGenWorker;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.objects.rending.Mat4f;
|
||||
import com.seibel.lod.proxy.GlProxy;
|
||||
import com.seibel.lod.render.LodRenderer;
|
||||
import com.seibel.lod.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.util.ThreadMapUtil;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
/**
|
||||
* This holds the methods that should be called
|
||||
* by the host mod loader (Fabric, Forge, etc.).
|
||||
* Specifically for the client.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public class ClientApi
|
||||
{
|
||||
public static final ClientApi INSTANCE = new ClientApi();
|
||||
public static final Logger LOGGER = LogManager.getLogger("LOD");
|
||||
|
||||
public static LodRenderer renderer = new LodRenderer(ApiShared.lodBufferBuilder);
|
||||
|
||||
|
||||
private final MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
|
||||
private final EventApi eventApi = EventApi.INSTANCE;
|
||||
|
||||
/**
|
||||
* there is some setup that should only happen once,
|
||||
* once this is true that setup has completed
|
||||
*/
|
||||
private boolean firstTimeSetupComplete = false;
|
||||
private boolean configOverrideReminderPrinted = false;
|
||||
|
||||
|
||||
|
||||
private ClientApi()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void renderLods(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks)
|
||||
{
|
||||
// comment out when creating a release
|
||||
// applyConfigOverrides();
|
||||
|
||||
// clear any out of date objects
|
||||
mc.clearFrameObjectCache();
|
||||
|
||||
try
|
||||
{
|
||||
// only run the first time setup once
|
||||
if (!firstTimeSetupComplete)
|
||||
firstFrameSetup();
|
||||
|
||||
|
||||
if (mc.getPlayer() == null || ApiShared.lodWorld.getIsWorldNotLoaded())
|
||||
return;
|
||||
|
||||
LodDimension lodDim = ApiShared.lodWorld.getLodDimension(mc.getCurrentDimension());
|
||||
if (lodDim == null)
|
||||
return;
|
||||
|
||||
DetailDistanceUtil.updateSettings();
|
||||
eventApi.viewDistanceChangedEvent();
|
||||
eventApi.playerMoveEvent(lodDim);
|
||||
|
||||
lodDim.cutRegionNodesAsync((int) mc.getPlayer().getX(), (int) mc.getPlayer().getZ());
|
||||
lodDim.expandOrLoadRegionsAsync((int) mc.getPlayer().getX(), (int) mc.getPlayer().getZ());
|
||||
|
||||
|
||||
// Note to self:
|
||||
// if "unspecified" shows up in the pie chart, it is
|
||||
// possibly because the amount of time between sections
|
||||
// is too small for the profiler to measure
|
||||
IProfiler profiler = mc.getProfiler();
|
||||
profiler.pop(); // get out of "terrain"
|
||||
profiler.push("LOD");
|
||||
|
||||
|
||||
ClientApi.renderer.drawLODs(lodDim, mcModelViewMatrix, mcProjectionMatrix, partialTicks, mc.getProfiler());
|
||||
|
||||
profiler.pop(); // end LOD
|
||||
profiler.push("terrain"); // go back into "terrain"
|
||||
|
||||
|
||||
// these can't be set until after the buffers are built (in renderer.drawLODs)
|
||||
// otherwise the buffers may be set to the wrong size, or not changed at all
|
||||
ApiShared.previousChunkRenderDistance = mc.getRenderDistance();
|
||||
ApiShared.previousLodRenderDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ClientApi.LOGGER.error("client proxy: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/** used in a development environment to change settings on the fly */
|
||||
private void applyConfigOverrides()
|
||||
{
|
||||
// remind the developer(s) that the config override is active
|
||||
if (!configOverrideReminderPrinted)
|
||||
{
|
||||
// TODO add a send message method to the MC wrapper
|
||||
// mc.getPlayer().sendMessage(new StringTextComponent("LOD experimental build 1.5.1"), mc.getPlayer().getUUID());
|
||||
// mc.getPlayer().sendMessage(new StringTextComponent("Here be dragons!"), mc.getPlayer().getUUID());
|
||||
|
||||
mc.getPlayer().sendMessage(new StringTextComponent("Debug settings enabled!"), mc.getPlayer().getUUID());
|
||||
configOverrideReminderPrinted = true;
|
||||
}
|
||||
|
||||
// LodConfig.CLIENT.graphics.drawResolution.set(HorizontalResolution.BLOCK);
|
||||
// LodConfig.CLIENT.worldGenerator.generationResolution.set(HorizontalResolution.BLOCK);
|
||||
// requires a world restart?
|
||||
// LodConfig.CLIENT.worldGenerator.lodQualityMode.set(VerticalQuality.VOXEL);
|
||||
|
||||
// LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.set(FogDistance.FAR);
|
||||
// LodConfig.CLIENT.graphics.fogQualityOption.fogDrawOverride.set(FogDrawOverride.FANCY);
|
||||
// LodConfig.CLIENT.graphics.fogQualityOption.disableVanillaFog.set(true);
|
||||
// LodConfig.CLIENT.graphics.shadingMode.set(ShadingMode.DARKEN_SIDES);
|
||||
|
||||
// LodConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.set(VanillaOverdraw.DYNAMIC);
|
||||
|
||||
// LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.set(GpuUploadMethod.BUFFER_STORAGE);
|
||||
|
||||
// LodConfig.CLIENT.worldGenerator.distanceGenerationMode.set(DistanceGenerationMode.SURFACE);
|
||||
// LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.set(128);
|
||||
// LodConfig.CLIENT.worldGenerator.lodDistanceCalculatorType.set(DistanceCalculatorType.LINEAR);
|
||||
// LodConfig.CLIENT.worldGenerator.allowUnstableFeatureGeneration.set(false);
|
||||
|
||||
// LodConfig.CLIENT.buffers.rebuildTimes.set(BufferRebuildTimes.FREQUENT);
|
||||
|
||||
LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.set(true);
|
||||
// LodConfig.CLIENT.debugging.debugMode.set(DebugMode.SHOW_DETAIL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// Lod maintenance //
|
||||
//=================//
|
||||
|
||||
/** This event is called once during the first frame Minecraft renders in the world. */
|
||||
public void firstFrameSetup()
|
||||
{
|
||||
// make sure the GlProxy is created before the LodBufferBuilder needs it
|
||||
GlProxy.getInstance();
|
||||
|
||||
firstTimeSetupComplete = true;
|
||||
}
|
||||
|
||||
/** this method reset some static data every time we change world */
|
||||
private void resetMod()
|
||||
{
|
||||
// TODO when should this be used?
|
||||
ThreadMapUtil.clearMaps();
|
||||
LodGenWorker.restartExecutorService();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.lodApi;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.seibel.lod.builders.worldGeneration.LodWorldGenerator;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.objects.lod.RegionPos;
|
||||
import com.seibel.lod.render.LodRenderer;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.util.ThreadMapUtil;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkWrapper;
|
||||
import com.seibel.lod.wrappers.World.DimensionTypeWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
|
||||
/**
|
||||
* This holds the methods that should be called
|
||||
* by the host mod loader (Fabric, Forge, etc.).
|
||||
* Specifically server and client events.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public class EventApi
|
||||
{
|
||||
public static final EventApi INSTANCE = new EventApi();
|
||||
|
||||
private final MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
|
||||
|
||||
/**
|
||||
* can be set if we want to recalculate variables related
|
||||
* to the LOD view distance
|
||||
*/
|
||||
private boolean recalculateWidths = false;
|
||||
|
||||
|
||||
private EventApi()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// tick events //
|
||||
//=============//
|
||||
|
||||
public void serverTickEvent()
|
||||
{
|
||||
if (mc.getPlayer() == null || ApiShared.lodWorld.getIsWorldNotLoaded())
|
||||
return;
|
||||
|
||||
LodDimension lodDim = ApiShared.lodWorld.getLodDimension(DimensionTypeWrapper.getDimensionTypeWrapper(mc.getPlayer().level.dimensionType()));
|
||||
if (lodDim == null)
|
||||
return;
|
||||
|
||||
LodWorldGenerator.INSTANCE.queueGenerationRequests(lodDim, ClientApi.renderer, ApiShared.lodBuilder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// world events //
|
||||
//==============//
|
||||
|
||||
public void chunkLoadEvent(ChunkWrapper chunk, DimensionTypeWrapper dimType)
|
||||
{
|
||||
ApiShared.lodBuilder.generateLodNodeAsync(chunk, ApiShared.lodWorld, dimType, DistanceGenerationMode.SERVER);
|
||||
}
|
||||
|
||||
public void worldSaveEvent()
|
||||
{
|
||||
ApiShared.lodWorld.saveAllDimensions();
|
||||
}
|
||||
|
||||
/** This is also called when a new dimension loads */
|
||||
public void worldLoadEvent(WorldWrapper world)
|
||||
{
|
||||
DataPointUtil.worldHeight = world.getHeight();
|
||||
//LodNodeGenWorker.restartExecutorService();
|
||||
//ThreadMapUtil.clearMaps();
|
||||
|
||||
// the player just loaded a new world/dimension
|
||||
ApiShared.lodWorld.selectWorld(LodUtil.getWorldID(world));
|
||||
|
||||
// make sure the correct LODs are being rendered
|
||||
// (if this isn't done the previous world's LODs may be drawn)
|
||||
ClientApi.renderer.regenerateLODsNextFrame();
|
||||
}
|
||||
|
||||
public void worldUnloadEvent()
|
||||
{
|
||||
// the player just unloaded a world/dimension
|
||||
ThreadMapUtil.clearMaps();
|
||||
|
||||
|
||||
if (mc.getConnection().getLevel() == null)
|
||||
{
|
||||
// the player just left the server
|
||||
|
||||
// TODO should "resetMod()" be called here? -James
|
||||
|
||||
// if this isn't done unfinished tasks may be left in the queue
|
||||
// preventing new LodChunks form being generated
|
||||
//LodNodeGenWorker.restartExecutorService(); // TODO why was this commented out? -James
|
||||
//ThreadMapUtil.clearMaps();
|
||||
|
||||
LodWorldGenerator.INSTANCE.numberOfChunksWaitingToGenerate.set(0);
|
||||
ApiShared.lodWorld.deselectWorld();
|
||||
|
||||
|
||||
// prevent issues related to the buffer builder
|
||||
// breaking when changing worlds.
|
||||
ClientApi.renderer.destroyBuffers();
|
||||
recalculateWidths = true;
|
||||
ClientApi.renderer = new LodRenderer(ApiShared.lodBufferBuilder);
|
||||
|
||||
|
||||
// make sure the nulled objects are freed.
|
||||
// (this prevents an out of memory error when
|
||||
// changing worlds)
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
public void blockChangeEvent(ChunkWrapper chunk, DimensionTypeWrapper dimType)
|
||||
{
|
||||
// recreate the LOD where the blocks were changed
|
||||
ApiShared.lodBuilder.generateLodNodeAsync(chunk, ApiShared.lodWorld, dimType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// Misc Events //
|
||||
//=============//
|
||||
|
||||
public void onKeyInput(int key, int keyAction)
|
||||
{
|
||||
if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get()
|
||||
&& key == GLFW.GLFW_KEY_F4 && keyAction == GLFW.GLFW_PRESS)
|
||||
{
|
||||
LodConfig.CLIENT.advancedModOptions.debugging.debugMode.set(LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get().getNext());
|
||||
}
|
||||
|
||||
if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get()
|
||||
&& key == GLFW.GLFW_KEY_F6 && keyAction == GLFW.GLFW_PRESS)
|
||||
{
|
||||
LodConfig.CLIENT.advancedModOptions.debugging.drawLods.set(!LodConfig.CLIENT.advancedModOptions.debugging.drawLods.get());
|
||||
}
|
||||
}
|
||||
|
||||
/** Re-centers the given LodDimension if it needs to be. */
|
||||
public void playerMoveEvent(LodDimension lodDim)
|
||||
{
|
||||
// make sure the dimension is centered
|
||||
RegionPos playerRegionPos = new RegionPos(mc.getPlayerBlockPos());
|
||||
RegionPos worldRegionOffset = new RegionPos(playerRegionPos.x - lodDim.getCenterRegionPosX(), playerRegionPos.z - lodDim.getCenterRegionPosZ());
|
||||
if (worldRegionOffset.x != 0 || worldRegionOffset.z != 0)
|
||||
{
|
||||
ApiShared.lodWorld.saveAllDimensions();
|
||||
lodDim.move(worldRegionOffset);
|
||||
//LOGGER.info("offset: " + worldRegionOffset.x + "," + worldRegionOffset.z + "\t center: " + lodDim.getCenterX() + "," + lodDim.getCenterZ());
|
||||
}
|
||||
}
|
||||
|
||||
/** Re-sizes all LodDimensions if they need to be. */
|
||||
public void viewDistanceChangedEvent()
|
||||
{
|
||||
// calculate how wide the dimension(s) should be in regions
|
||||
int chunksWide;
|
||||
if (mc.getClientWorld().dimensionType().hasCeiling())
|
||||
chunksWide = Math.min(LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * 2 + 1;
|
||||
else
|
||||
chunksWide = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * 2 + 1;
|
||||
|
||||
int newWidth = (int) Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS);
|
||||
// make sure we have an odd number of regions
|
||||
newWidth += (newWidth & 1) == 0 ? 1 : 2;
|
||||
|
||||
// do the dimensions need to change in size?
|
||||
if (ApiShared.lodBuilder.defaultDimensionWidthInRegions != newWidth || recalculateWidths)
|
||||
{
|
||||
ApiShared.lodWorld.saveAllDimensions();
|
||||
|
||||
// update the dimensions to fit the new width
|
||||
ApiShared.lodWorld.resizeDimensionRegionWidth(newWidth);
|
||||
ApiShared.lodBuilder.defaultDimensionWidthInRegions = newWidth;
|
||||
ClientApi.renderer.setupBuffers(ApiShared.lodWorld.getLodDimension(DimensionTypeWrapper.getDimensionTypeWrapper(mc.getClientWorld().dimensionType())));
|
||||
|
||||
recalculateWidths = false;
|
||||
//LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth );
|
||||
}
|
||||
DetailDistanceUtil.updateSettings();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -19,13 +19,14 @@
|
||||
|
||||
package com.seibel.lod.mixin;
|
||||
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.seibel.lod.api.ClientApi;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.objects.rending.Mat4f;
|
||||
import com.seibel.lod.wrappers.McObjectConverter;
|
||||
|
||||
@@ -62,8 +63,18 @@ public class MixinWorldRenderer
|
||||
// only render before solid blocks
|
||||
if (renderType.equals(RenderType.solid()))
|
||||
{
|
||||
// get MC's current projection matrix
|
||||
float[] mcProjMatrixRaw = new float[16];
|
||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||
// OpenGl outputs their matrices in col,row form instead of row,col
|
||||
// (or maybe vice versa I have no idea :P)
|
||||
mcProjectionMatrix.transpose();
|
||||
|
||||
|
||||
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
|
||||
ClientApi.renderLods(mcModelViewMatrix, previousPartialTicks);
|
||||
|
||||
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ package com.seibel.lod.objects;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.util.LevelPosUtil;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
@@ -60,7 +60,7 @@ public class PosToRenderContainer
|
||||
{
|
||||
// This is might be due to dimensions having a different width
|
||||
// when first loading in
|
||||
ClientProxy.LOGGER.error("Unable to addPosToRender. numberOfPosToRender [" + numberOfPosToRender + "] detailLevel [" + detailLevel + "] Pos [" + posX + "," + posZ + "]");
|
||||
ClientApi.LOGGER.error("Unable to addPosToRender. numberOfPosToRender [" + numberOfPosToRender + "] detailLevel [" + detailLevel + "] Pos [" + posX + "," + posZ + "]");
|
||||
numberOfPosToRender++; // incrementing so we can see how many pos over the limit we would go
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.GenerationPriority;
|
||||
import com.seibel.lod.enums.VerticalQuality;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.GenerationPriority;
|
||||
import com.seibel.lod.enums.config.VerticalQuality;
|
||||
import com.seibel.lod.handlers.LodDimensionFileHandler;
|
||||
import com.seibel.lod.objects.PosToGenerateContainer;
|
||||
import com.seibel.lod.objects.PosToRenderContainer;
|
||||
@@ -37,11 +37,10 @@ import com.seibel.lod.util.LevelPosUtil;
|
||||
import com.seibel.lod.util.LodThreadFactory;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
import com.seibel.lod.wrappers.World.DimensionTypeWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.server.ServerChunkProvider;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
|
||||
/**
|
||||
@@ -54,11 +53,11 @@ import net.minecraft.world.server.ServerWorld;
|
||||
*
|
||||
* @author Leonardo Amato
|
||||
* @author James Seibel
|
||||
* @version 10-10-2021
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public class LodDimension
|
||||
{
|
||||
public final DimensionType dimension;
|
||||
public final DimensionTypeWrapper dimension;
|
||||
|
||||
/** measured in regions */
|
||||
private volatile int width;
|
||||
@@ -97,7 +96,7 @@ public class LodDimension
|
||||
* Creates the dimension centered at (0,0)
|
||||
* @param newWidth in regions
|
||||
*/
|
||||
public LodDimension(DimensionType newDimension, LodWorld lodWorld, int newWidth)
|
||||
public LodDimension(DimensionTypeWrapper newDimension, LodWorld lodWorld, int newWidth)
|
||||
{
|
||||
lastCutChunk = null;
|
||||
lastExpandedChunk = null;
|
||||
@@ -110,17 +109,14 @@ public class LodDimension
|
||||
{
|
||||
try
|
||||
{
|
||||
// determine the save folder
|
||||
File saveDir;
|
||||
if (mc.hasSinglePlayerServer())
|
||||
{
|
||||
// local world
|
||||
|
||||
ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(newDimension);
|
||||
|
||||
// provider needs a separate variable to prevent
|
||||
// the compiler from complaining
|
||||
ServerChunkProvider provider = serverWorld.getChunkSource();
|
||||
saveDir = new File(provider.dataStorage.dataFolder.getCanonicalFile().getPath() + File.separatorChar + "lod");
|
||||
WorldWrapper serverWorld = LodUtil.getServerWorldFromDimension(newDimension);
|
||||
saveDir = new File(serverWorld.getSaveFolder().getCanonicalFile().getPath() + File.separatorChar + "lod");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
package com.seibel.lod.objects.lod;
|
||||
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.VerticalQuality;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.VerticalQuality;
|
||||
import com.seibel.lod.objects.PosToGenerateContainer;
|
||||
import com.seibel.lod.objects.PosToRenderContainer;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
|
||||
@@ -22,10 +22,8 @@ package com.seibel.lod.objects.lod;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.wrappers.World.DimensionTypeWrapper;
|
||||
import net.minecraft.world.DimensionType;
|
||||
|
||||
/**
|
||||
* This stores all LODs for a given world.
|
||||
@@ -108,18 +106,18 @@ public class LodWorld
|
||||
if (lodDimensions == null)
|
||||
return;
|
||||
|
||||
lodDimensions.put(DimensionTypeWrapper.getDimensionTypeWrapper(newDimension.dimension), newDimension);
|
||||
lodDimensions.put(newDimension.dimension, newDimension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null if no LodDimension exists for the given dimension
|
||||
*/
|
||||
public LodDimension getLodDimension(DimensionType dimension)
|
||||
public LodDimension getLodDimension(DimensionTypeWrapper dimType)
|
||||
{
|
||||
if (lodDimensions == null)
|
||||
return null;
|
||||
|
||||
return lodDimensions.get(DimensionTypeWrapper.getDimensionTypeWrapper(dimension));
|
||||
return lodDimensions.get(dimType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,7 +145,7 @@ public class LodWorld
|
||||
|
||||
// TODO we should only print this if lods were actually saved to file
|
||||
// but that requires a LodDimension.hasDirtyRegions() method or something similar
|
||||
ClientProxy.LOGGER.info("Saving LODs");
|
||||
ClientApi.LOGGER.info("Saving LODs");
|
||||
|
||||
for (DimensionTypeWrapper key : lodDimensions.keySet())
|
||||
lodDimensions.get(key).saveDirtyRegionsToFileAsync();
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.objects.rending;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
package com.seibel.lod.objects.rending;
|
||||
|
||||
import com.seibel.lod.enums.FogDistance;
|
||||
import com.seibel.lod.enums.FogQuality;
|
||||
import com.seibel.lod.enums.rendering.FogDistance;
|
||||
import com.seibel.lod.enums.rendering.FogQuality;
|
||||
|
||||
/**
|
||||
* This object is just a replacement for an array
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.objects.rending;
|
||||
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
@@ -19,31 +19,11 @@
|
||||
|
||||
package com.seibel.lod.proxy;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
|
||||
import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder;
|
||||
import com.seibel.lod.builders.lodBuilding.LodBuilder;
|
||||
import com.seibel.lod.builders.worldGeneration.LodGenWorker;
|
||||
import com.seibel.lod.builders.worldGeneration.LodWorldGenerator;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.objects.lod.LodWorld;
|
||||
import com.seibel.lod.objects.lod.RegionPos;
|
||||
import com.seibel.lod.objects.rending.Mat4f;
|
||||
import com.seibel.lod.render.LodRenderer;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.util.ThreadMapUtil;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
import com.seibel.lod.lodApi.EventApi;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkWrapper;
|
||||
import com.seibel.lod.wrappers.World.DimensionTypeWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraftforge.client.event.InputEvent;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
@@ -54,359 +34,71 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
/**
|
||||
* This handles all events sent to the client,
|
||||
* and is the starting point for most of the mod.
|
||||
*
|
||||
* @author James_Seibel
|
||||
* @version 11-8-2021
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public class ClientProxy
|
||||
{
|
||||
public static final Logger LOGGER = LogManager.getLogger("LOD");
|
||||
|
||||
/**
|
||||
* there is some setup that should only happen once,
|
||||
* once this is true that setup has completed
|
||||
*/
|
||||
private boolean firstTimeSetupComplete = false;
|
||||
|
||||
private static final LodWorld lodWorld = new LodWorld();
|
||||
private static final LodBuilder lodBuilder = new LodBuilder();
|
||||
private static final LodBufferBuilder lodBufferBuilder = new LodBufferBuilder();
|
||||
private static LodRenderer renderer = new LodRenderer(lodBufferBuilder);
|
||||
private static final LodWorldGenerator lodWorldGenerator = LodWorldGenerator.INSTANCE;
|
||||
|
||||
private boolean configOverrideReminderPrinted = false;
|
||||
|
||||
private final MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
|
||||
private final EventApi eventApi = EventApi.INSTANCE;
|
||||
|
||||
|
||||
/** This is used to determine if the LODs should be regenerated */
|
||||
public static int previousChunkRenderDistance = 0;
|
||||
/** This is used to determine if the LODs should be regenerated */
|
||||
public static int previousLodRenderDistance = 0;
|
||||
|
||||
/**
|
||||
* can be set if we want to recalculate variables related
|
||||
* to the LOD view distance
|
||||
*/
|
||||
private boolean recalculateWidths = false;
|
||||
|
||||
public ClientProxy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//==============//
|
||||
// render event //
|
||||
//==============//
|
||||
|
||||
/** Do any setup that is required to draw LODs and then tell the LodRenderer to draw. */
|
||||
public void renderLods(Mat4f mcModelViewMatrix, float partialTicks)
|
||||
{
|
||||
// comment out when creating a release
|
||||
// applyConfigOverrides();
|
||||
|
||||
// clear any out of date objects
|
||||
mc.clearFrameObjectCache();
|
||||
|
||||
try
|
||||
{
|
||||
// only run the first time setup once
|
||||
if (!firstTimeSetupComplete)
|
||||
firstFrameSetup();
|
||||
|
||||
|
||||
if (mc.getPlayer() == null || lodWorld.getIsWorldNotLoaded())
|
||||
return;
|
||||
|
||||
LodDimension lodDim = lodWorld.getLodDimension(mc.getCurrentDimension());
|
||||
if (lodDim == null)
|
||||
return;
|
||||
|
||||
DetailDistanceUtil.updateSettings();
|
||||
viewDistanceChangedEvent();
|
||||
playerMoveEvent(lodDim);
|
||||
|
||||
lodDim.cutRegionNodesAsync((int) mc.getPlayer().getX(), (int) mc.getPlayer().getZ());
|
||||
lodDim.expandOrLoadRegionsAsync((int) mc.getPlayer().getX(), (int) mc.getPlayer().getZ());
|
||||
|
||||
|
||||
// get the default projection matrix, so we can
|
||||
// reset it after drawing the LODs
|
||||
float[] mcProjMatrixRaw = new float[16];
|
||||
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
|
||||
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
|
||||
// OpenGl outputs their matrices in col,row form instead of row,col
|
||||
// (or maybe vice versa I have no idea :P)
|
||||
mcProjectionMatrix.transpose();
|
||||
|
||||
// Note to self:
|
||||
// if "unspecified" shows up in the pie chart, it is
|
||||
// possibly because the amount of time between sections
|
||||
// is too small for the profiler to measure
|
||||
IProfiler profiler = mc.getProfiler();
|
||||
profiler.pop(); // get out of "terrain"
|
||||
profiler.push("LOD");
|
||||
|
||||
|
||||
renderer.drawLODs(lodDim, mcModelViewMatrix, mcProjectionMatrix, partialTicks, mc.getProfiler());
|
||||
|
||||
profiler.pop(); // end LOD
|
||||
profiler.push("terrain"); // go back into "terrain"
|
||||
|
||||
|
||||
// these can't be set until after the buffers are built (in renderer.drawLODs)
|
||||
// otherwise the buffers may be set to the wrong size, or not changed at all
|
||||
previousChunkRenderDistance = mc.getRenderDistance();
|
||||
previousLodRenderDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("client proxy: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/** used in a development environment to change settings on the fly */
|
||||
private void applyConfigOverrides()
|
||||
{
|
||||
// remind the developer(s) that the config override is active
|
||||
if (!configOverrideReminderPrinted)
|
||||
{
|
||||
// TODO add a send message method to the MC wrapper
|
||||
// mc.getPlayer().sendMessage(new StringTextComponent("LOD experimental build 1.5.1"), mc.getPlayer().getUUID());
|
||||
// mc.getPlayer().sendMessage(new StringTextComponent("Here be dragons!"), mc.getPlayer().getUUID());
|
||||
|
||||
mc.getPlayer().sendMessage(new StringTextComponent("Debug settings enabled!"), mc.getPlayer().getUUID());
|
||||
configOverrideReminderPrinted = true;
|
||||
}
|
||||
|
||||
// LodConfig.CLIENT.graphics.drawResolution.set(HorizontalResolution.BLOCK);
|
||||
// LodConfig.CLIENT.worldGenerator.generationResolution.set(HorizontalResolution.BLOCK);
|
||||
// requires a world restart?
|
||||
// LodConfig.CLIENT.worldGenerator.lodQualityMode.set(VerticalQuality.VOXEL);
|
||||
|
||||
// LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.set(FogDistance.FAR);
|
||||
// LodConfig.CLIENT.graphics.fogQualityOption.fogDrawOverride.set(FogDrawOverride.FANCY);
|
||||
// LodConfig.CLIENT.graphics.fogQualityOption.disableVanillaFog.set(true);
|
||||
// LodConfig.CLIENT.graphics.shadingMode.set(ShadingMode.DARKEN_SIDES);
|
||||
|
||||
// LodConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.set(VanillaOverdraw.DYNAMIC);
|
||||
|
||||
// LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.set(GpuUploadMethod.BUFFER_STORAGE);
|
||||
|
||||
// LodConfig.CLIENT.worldGenerator.distanceGenerationMode.set(DistanceGenerationMode.SURFACE);
|
||||
// LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.set(128);
|
||||
// LodConfig.CLIENT.worldGenerator.lodDistanceCalculatorType.set(DistanceCalculatorType.LINEAR);
|
||||
// LodConfig.CLIENT.worldGenerator.allowUnstableFeatureGeneration.set(false);
|
||||
|
||||
// LodConfig.CLIENT.buffers.rebuildTimes.set(BufferRebuildTimes.FREQUENT);
|
||||
|
||||
LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.set(true);
|
||||
// LodConfig.CLIENT.debugging.debugMode.set(DebugMode.SHOW_DETAIL);
|
||||
}
|
||||
|
||||
|
||||
//==============//
|
||||
// forge events //
|
||||
//==============//
|
||||
|
||||
@SubscribeEvent
|
||||
public void serverTickEvent(TickEvent.ServerTickEvent event)
|
||||
{
|
||||
if (mc.getPlayer() == null || lodWorld.getIsWorldNotLoaded())
|
||||
return;
|
||||
|
||||
LodDimension lodDim = lodWorld.getLodDimension(mc.getPlayer().level.dimensionType());
|
||||
if (lodDim == null)
|
||||
return;
|
||||
|
||||
lodWorldGenerator.queueGenerationRequests(lodDim, renderer, lodBuilder);
|
||||
eventApi.serverTickEvent();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void chunkLoadEvent(ChunkEvent.Load event)
|
||||
{
|
||||
lodBuilder.generateLodNodeAsync(new ChunkWrapper(event.getChunk()), lodWorld, event.getWorld(), DistanceGenerationMode.SERVER);
|
||||
eventApi.chunkLoadEvent(new ChunkWrapper(event.getChunk()), DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType()));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void worldSaveEvent(WorldEvent.Save event)
|
||||
{
|
||||
lodWorld.saveAllDimensions();
|
||||
eventApi.worldSaveEvent();
|
||||
}
|
||||
|
||||
/** This is also called when a new dimension loads */
|
||||
@SubscribeEvent
|
||||
public void worldLoadEvent(WorldEvent.Load event)
|
||||
{
|
||||
DataPointUtil.worldHeight = event.getWorld().getHeight();
|
||||
//LodNodeGenWorker.restartExecutorService();
|
||||
//ThreadMapUtil.clearMaps();
|
||||
|
||||
// the player just loaded a new world/dimension
|
||||
lodWorld.selectWorld(LodUtil.getWorldID(event.getWorld()));
|
||||
|
||||
// make sure the correct LODs are being rendered
|
||||
// (if this isn't done the previous world's LODs may be drawn)
|
||||
renderer.regenerateLODsNextFrame();
|
||||
eventApi.worldLoadEvent(WorldWrapper.getWorldWrapper(event.getWorld()));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void worldUnloadEvent(WorldEvent.Unload event)
|
||||
{
|
||||
// the player just unloaded a world/dimension
|
||||
ThreadMapUtil.clearMaps();
|
||||
|
||||
|
||||
if (mc.getConnection().getLevel() == null)
|
||||
{
|
||||
// the player just left the server
|
||||
|
||||
// TODO should "resetMod()" be called here? -James
|
||||
|
||||
// if this isn't done unfinished tasks may be left in the queue
|
||||
// preventing new LodChunks form being generated
|
||||
//LodNodeGenWorker.restartExecutorService(); // TODO why was this commented out? -James
|
||||
//ThreadMapUtil.clearMaps();
|
||||
|
||||
LodWorldGenerator.INSTANCE.numberOfChunksWaitingToGenerate.set(0);
|
||||
lodWorld.deselectWorld();
|
||||
|
||||
|
||||
// prevent issues related to the buffer builder
|
||||
// breaking when changing worlds.
|
||||
renderer.destroyBuffers();
|
||||
recalculateWidths = true;
|
||||
renderer = new LodRenderer(lodBufferBuilder);
|
||||
|
||||
|
||||
// make sure the nulled objects are freed.
|
||||
// (this prevents an out of memory error when
|
||||
// changing worlds)
|
||||
System.gc();
|
||||
}
|
||||
eventApi.worldUnloadEvent();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void blockChangeEvent(BlockEvent event)
|
||||
{
|
||||
// we only care about certain block events
|
||||
if (event.getClass() == BlockEvent.BreakEvent.class ||
|
||||
event.getClass() == BlockEvent.EntityPlaceEvent.class ||
|
||||
event.getClass() == BlockEvent.EntityMultiPlaceEvent.class ||
|
||||
event.getClass() == BlockEvent.FluidPlaceBlockEvent.class ||
|
||||
event.getClass() == BlockEvent.PortalSpawnEvent.class)
|
||||
{
|
||||
ChunkWrapper chunk = new ChunkWrapper(event.getWorld().getChunk(event.getPos()));
|
||||
DimensionTypeWrapper dimType = DimensionTypeWrapper.getDimensionTypeWrapper(event.getWorld().dimensionType());
|
||||
|
||||
// recreate the LOD where the blocks were changed
|
||||
lodBuilder.generateLodNodeAsync(new ChunkWrapper(event.getWorld().getChunk(event.getPos())), lodWorld, event.getWorld());
|
||||
eventApi.blockChangeEvent(chunk, dimType);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKeyInput(InputEvent.KeyInputEvent event)
|
||||
{
|
||||
if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get()
|
||||
&& event.getKey() == GLFW.GLFW_KEY_F4 && event.getAction() == GLFW.GLFW_PRESS)
|
||||
{
|
||||
LodConfig.CLIENT.advancedModOptions.debugging.debugMode.set(LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get().getNext());
|
||||
}
|
||||
|
||||
if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get()
|
||||
&& event.getKey() == GLFW.GLFW_KEY_F6 && event.getAction() == GLFW.GLFW_PRESS)
|
||||
{
|
||||
LodConfig.CLIENT.advancedModOptions.debugging.drawLods.set(!LodConfig.CLIENT.advancedModOptions.debugging.drawLods.get());
|
||||
}
|
||||
eventApi.onKeyInput(event.getKey(), event.getAction());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// LOD events //
|
||||
//============//
|
||||
|
||||
/** Re-centers the given LodDimension if it needs to be. */
|
||||
private void playerMoveEvent(LodDimension lodDim)
|
||||
{
|
||||
// make sure the dimension is centered
|
||||
RegionPos playerRegionPos = new RegionPos(mc.getPlayerBlockPos());
|
||||
RegionPos worldRegionOffset = new RegionPos(playerRegionPos.x - lodDim.getCenterRegionPosX(), playerRegionPos.z - lodDim.getCenterRegionPosZ());
|
||||
if (worldRegionOffset.x != 0 || worldRegionOffset.z != 0)
|
||||
{
|
||||
lodWorld.saveAllDimensions();
|
||||
lodDim.move(worldRegionOffset);
|
||||
//LOGGER.info("offset: " + worldRegionOffset.x + "," + worldRegionOffset.z + "\t center: " + lodDim.getCenterX() + "," + lodDim.getCenterZ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Re-sizes all LodDimensions if they need to be. */
|
||||
private void viewDistanceChangedEvent()
|
||||
{
|
||||
// calculate how wide the dimension(s) should be in regions
|
||||
int chunksWide;
|
||||
if (mc.getClientLevel().dimensionType().hasCeiling())
|
||||
chunksWide = Math.min(LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * 2 + 1;
|
||||
else
|
||||
chunksWide = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * 2 + 1;
|
||||
|
||||
int newWidth = (int) Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS);
|
||||
// make sure we have an odd number of regions
|
||||
newWidth += (newWidth & 1) == 0 ? 1 : 2;
|
||||
|
||||
// do the dimensions need to change in size?
|
||||
if (lodBuilder.defaultDimensionWidthInRegions != newWidth || recalculateWidths)
|
||||
{
|
||||
lodWorld.saveAllDimensions();
|
||||
|
||||
// update the dimensions to fit the new width
|
||||
lodWorld.resizeDimensionRegionWidth(newWidth);
|
||||
lodBuilder.defaultDimensionWidthInRegions = newWidth;
|
||||
renderer.setupBuffers(lodWorld.getLodDimension(mc.getClientLevel().dimensionType()));
|
||||
|
||||
recalculateWidths = false;
|
||||
//LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth );
|
||||
}
|
||||
DetailDistanceUtil.updateSettings();
|
||||
}
|
||||
|
||||
|
||||
/** This event is called once during the first frame Minecraft renders in the world. */
|
||||
public void firstFrameSetup()
|
||||
{
|
||||
// make sure the GlProxy is created before the LodBufferBuilder needs it
|
||||
GlProxy.getInstance();
|
||||
|
||||
firstTimeSetupComplete = true;
|
||||
}
|
||||
|
||||
/** this method reset some static data every time we change world */
|
||||
private void resetMod()
|
||||
{
|
||||
// TODO when should this be used?
|
||||
ThreadMapUtil.clearMaps();
|
||||
LodGenWorker.restartExecutorService();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// public getters //
|
||||
//================//
|
||||
|
||||
public static LodWorld getLodWorld()
|
||||
{
|
||||
return lodWorld;
|
||||
}
|
||||
|
||||
public static LodBuilder getLodBuilder()
|
||||
{
|
||||
return lodBuilder;
|
||||
}
|
||||
|
||||
public static LodRenderer getRenderer()
|
||||
{
|
||||
return renderer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ import org.lwjgl.opengl.GLCapabilities;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.lod.ModInfo;
|
||||
import com.seibel.lod.enums.GlProxyContext;
|
||||
import com.seibel.lod.enums.rendering.GlProxyContext;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.render.shader.LodShader;
|
||||
import com.seibel.lod.render.shader.LodShaderProgram;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
@@ -85,7 +86,7 @@ public class GlProxy
|
||||
|
||||
private GlProxy()
|
||||
{
|
||||
ClientProxy.LOGGER.error("Creating " + GlProxy.class.getSimpleName() + "... If this is the last message you see in the log there must have been a OpenGL error.");
|
||||
ClientApi.LOGGER.error("Creating " + GlProxy.class.getSimpleName() + "... If this is the last message you see in the log there must have been a OpenGL error.");
|
||||
|
||||
// getting Minecraft's context has to be done on the render thread,
|
||||
// where the GL context is
|
||||
@@ -128,7 +129,7 @@ public class GlProxy
|
||||
// get any GPU related capabilities //
|
||||
//==================================//
|
||||
|
||||
ClientProxy.LOGGER.info("Lod Render OpenGL version [" + GL11.glGetString(GL11.GL_VERSION) + "].");
|
||||
ClientApi.LOGGER.info("Lod Render OpenGL version [" + GL11.glGetString(GL11.GL_VERSION) + "].");
|
||||
|
||||
// crash the game if the GPU doesn't support OpenGL 2.0
|
||||
if (!minecraftGlCapabilities.OpenGL20)
|
||||
@@ -152,11 +153,11 @@ public class GlProxy
|
||||
if (!bufferStorageSupported)
|
||||
{
|
||||
String fallBackVersion = mapBufferRangeSupported ? "3.0" : "1.5";
|
||||
ClientProxy.LOGGER.error("This GPU doesn't support Buffer Storage (OpenGL 4.5), falling back to OpenGL " + fallBackVersion + ". This may cause stuttering and reduced performance.");
|
||||
ClientApi.LOGGER.error("This GPU doesn't support Buffer Storage (OpenGL 4.5), falling back to OpenGL " + fallBackVersion + ". This may cause stuttering and reduced performance.");
|
||||
}
|
||||
|
||||
if (!fancyFogAvailable)
|
||||
ClientProxy.LOGGER.info("This GPU does not support GL_NV_fog_distance. This means that the fancy fog option will not be available.");
|
||||
ClientApi.LOGGER.info("This GPU does not support GL_NV_fog_distance. This means that the fancy fog option will not be available.");
|
||||
|
||||
|
||||
|
||||
@@ -189,7 +190,7 @@ public class GlProxy
|
||||
|
||||
|
||||
// GlProxy creation success
|
||||
ClientProxy.LOGGER.error(GlProxy.class.getSimpleName() + " creation successful. OpenGL smiles upon you this day.");
|
||||
ClientApi.LOGGER.error(GlProxy.class.getSimpleName() + " creation successful. OpenGL smiles upon you this day.");
|
||||
}
|
||||
|
||||
/** Creates all required shaders */
|
||||
@@ -231,7 +232,7 @@ public class GlProxy
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ClientProxy.LOGGER.error("Unable to compile shaders. Error: " + e.getMessage());
|
||||
ClientApi.LOGGER.error("Unable to compile shaders. Error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,17 +29,17 @@ import org.lwjgl.opengl.NVFogDistance;
|
||||
import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder;
|
||||
import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder.VertexBuffersAndOffset;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DebugMode;
|
||||
import com.seibel.lod.enums.FogDistance;
|
||||
import com.seibel.lod.enums.FogDrawOverride;
|
||||
import com.seibel.lod.enums.FogQuality;
|
||||
import com.seibel.lod.enums.GpuUploadMethod;
|
||||
import com.seibel.lod.enums.config.GpuUploadMethod;
|
||||
import com.seibel.lod.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.enums.rendering.FogDistance;
|
||||
import com.seibel.lod.enums.rendering.FogDrawOverride;
|
||||
import com.seibel.lod.enums.rendering.FogQuality;
|
||||
import com.seibel.lod.handlers.ReflectionHandler;
|
||||
import com.seibel.lod.lodApi.ApiShared;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.objects.lod.RegionPos;
|
||||
import com.seibel.lod.objects.rending.Mat4f;
|
||||
import com.seibel.lod.objects.rending.NearFarFogSettings;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.proxy.GlProxy;
|
||||
import com.seibel.lod.render.shader.LodShaderProgram;
|
||||
import com.seibel.lod.util.DetailDistanceUtil;
|
||||
@@ -251,7 +251,7 @@ public class LodRenderer
|
||||
Mat4f modelViewMatrix = offsetTheModelViewMatrix(mcModelViewMatrix, partialTicks);
|
||||
vanillaBlockRenderedDistance = mc.getRenderDistance() * LodUtil.CHUNK_WIDTH;
|
||||
// required for setupFog and setupProjectionMatrix
|
||||
if (mc.getClientLevel().dimensionType().hasCeiling())
|
||||
if (mc.getClientWorld().dimensionType().hasCeiling())
|
||||
farPlaneBlockDistance = Math.min(LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH;
|
||||
else
|
||||
farPlaneBlockDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH;
|
||||
@@ -802,7 +802,7 @@ public class LodRenderer
|
||||
//=============//
|
||||
|
||||
// check if the view distance changed
|
||||
if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get()
|
||||
if (ApiShared.previousLodRenderDistance != LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get()
|
||||
|| chunkRenderDistance != prevRenderDistance
|
||||
|| prevFogDistance != LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get())
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.io.InputStreamReader;
|
||||
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
|
||||
/**
|
||||
* This object holds a OpenGL reference to a shader
|
||||
@@ -76,7 +76,7 @@ public class LodShader
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
ClientProxy.LOGGER.error("Unable to load shader from file [" + path + "]. Error: " + e.getMessage());
|
||||
ClientApi.LOGGER.error("Unable to load shader from file [" + path + "]. Error: " + e.getMessage());
|
||||
}
|
||||
CharSequence shaderFileSource = stringBuilder.toString();
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ package com.seibel.lod.util;
|
||||
|
||||
import static com.seibel.lod.builders.bufferBuilding.LodBufferBuilder.skyLightPlayer;
|
||||
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
package com.seibel.lod.util;
|
||||
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.HorizontalQuality;
|
||||
import com.seibel.lod.enums.HorizontalResolution;
|
||||
import com.seibel.lod.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.enums.config.HorizontalQuality;
|
||||
import com.seibel.lod.enums.config.HorizontalResolution;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,13 +25,16 @@ import java.util.HashSet;
|
||||
|
||||
import com.seibel.lod.builders.bufferBuilding.lodTemplates.Box;
|
||||
import com.seibel.lod.config.LodConfig;
|
||||
import com.seibel.lod.enums.HorizontalResolution;
|
||||
import com.seibel.lod.enums.VanillaOverdraw;
|
||||
import com.seibel.lod.enums.config.HorizontalResolution;
|
||||
import com.seibel.lod.enums.config.VanillaOverdraw;
|
||||
import com.seibel.lod.objects.lod.LodDimension;
|
||||
import com.seibel.lod.objects.lod.RegionPos;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper;
|
||||
import com.seibel.lod.wrappers.World.DimensionTypeWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
|
||||
import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
@@ -42,12 +45,9 @@ import net.minecraft.server.integrated.IntegratedServer;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.DimensionType;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
import net.minecraft.world.gen.Heightmap;
|
||||
import net.minecraft.world.server.ServerChunkProvider;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
/**
|
||||
@@ -179,18 +179,18 @@ public class LodUtil
|
||||
* Gets the ServerWorld for the relevant dimension.
|
||||
* @return null if there is no ServerWorld for the given dimension
|
||||
*/
|
||||
public static ServerWorld getServerWorldFromDimension(DimensionType dimension)
|
||||
public static WorldWrapper getServerWorldFromDimension(DimensionTypeWrapper newDimension)
|
||||
{
|
||||
IntegratedServer server = mc.getSinglePlayerServer();
|
||||
if (server == null)
|
||||
return null;
|
||||
|
||||
Iterable<ServerWorld> worlds = server.getAllLevels();
|
||||
ServerWorld returnWorld = null;
|
||||
Iterable<WorldWrapper> worlds = mc.getAllServerWorlds();
|
||||
WorldWrapper returnWorld = null;
|
||||
|
||||
for (ServerWorld world : worlds)
|
||||
for (WorldWrapper world : worlds)
|
||||
{
|
||||
if (world.dimensionType() == dimension)
|
||||
if (world.getDimensionType() == newDimension)
|
||||
{
|
||||
returnWorld = world;
|
||||
break;
|
||||
@@ -238,7 +238,7 @@ public class LodUtil
|
||||
* world, if in multiplayer it will return the server name, IP,
|
||||
* and game version.
|
||||
*/
|
||||
public static String getWorldID(IWorld world)
|
||||
public static String getWorldID(WorldWrapper world)
|
||||
{
|
||||
if (mc.hasSinglePlayerServer())
|
||||
{
|
||||
@@ -266,26 +266,22 @@ public class LodUtil
|
||||
* This can be used to determine where to save files for a given
|
||||
* dimension.
|
||||
*/
|
||||
public static String getDimensionIDFromWorld(IWorld world)
|
||||
public static String getDimensionIDFromWorld(WorldWrapper world)
|
||||
{
|
||||
if (mc.hasSinglePlayerServer())
|
||||
{
|
||||
// this will return the world save location
|
||||
// and the dimension folder
|
||||
|
||||
ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(world.dimensionType());
|
||||
WorldWrapper serverWorld = LodUtil.getServerWorldFromDimension(world.getDimensionType());
|
||||
if (serverWorld == null)
|
||||
throw new NullPointerException("getDimensionIDFromWorld wasn't able to get the ServerWorld for the dimension " + world.dimensionType().effectsLocation().getPath());
|
||||
throw new NullPointerException("getDimensionIDFromWorld wasn't able to get the WorldWrapper for the dimension " + world.getDimensionType().getDimensionName());
|
||||
|
||||
ServerChunkProvider provider = serverWorld.getChunkSource();
|
||||
if (provider == null)
|
||||
throw new NullPointerException("getDimensionIDFromWorld wasn't able to get the ServerChunkProvider for the dimension " + world.dimensionType().effectsLocation().getPath());
|
||||
|
||||
return provider.dataStorage.dataFolder.toString();
|
||||
return serverWorld.getSaveFolder().toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return getServerId() + File.separatorChar + "dim_" + world.dimensionType().effectsLocation().getPath() + File.separatorChar;
|
||||
return getServerId() + File.separatorChar + "dim_" + world.getDimensionType().getDimensionName() + File.separatorChar;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ public class BlockColorWrapper
|
||||
else
|
||||
{
|
||||
isColored = true;
|
||||
texture = mc.getModelManager().getBlockModelShaper().getTexture(block.defaultBlockState(), mc.getClientLevel(), blockPosWrapper.getBlockPos());
|
||||
texture = mc.getModelManager().getBlockModelShaper().getTexture(block.defaultBlockState(), mc.getClientWorld(), blockPosWrapper.getBlockPos());
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.wrappers;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
@@ -21,14 +21,16 @@ package com.seibel.lod.wrappers;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.seibel.lod.ModInfo;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.lodApi.ClientApi;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper;
|
||||
import com.seibel.lod.wrappers.World.LevelWrapper;
|
||||
import com.seibel.lod.wrappers.World.DimensionTypeWrapper;
|
||||
import com.seibel.lod.wrappers.World.WorldWrapper;
|
||||
|
||||
import net.minecraft.client.GameSettings;
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -109,14 +111,14 @@ public class MinecraftWrapper
|
||||
return mc.hasSingleplayerServer();
|
||||
}
|
||||
|
||||
public DimensionType getCurrentDimension()
|
||||
public DimensionTypeWrapper getCurrentDimension()
|
||||
{
|
||||
return mc.player.level.dimensionType();
|
||||
return DimensionTypeWrapper.getDimensionTypeWrapper(mc.player.level.dimensionType());
|
||||
}
|
||||
|
||||
public String getCurrentDimensionId()
|
||||
{
|
||||
return LodUtil.getDimensionIDFromWorld(mc.level);
|
||||
return LodUtil.getDimensionIDFromWorld(WorldWrapper.getWorldWrapper(mc.level));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,12 +180,12 @@ public class MinecraftWrapper
|
||||
BlockPos playerPos = getPlayer().blockPosition();
|
||||
return new BlockPosWrapper(playerPos.getX(), playerPos.getY(), playerPos.getZ());
|
||||
}
|
||||
|
||||
|
||||
public ChunkPosWrapper getPlayerChunkPos()
|
||||
{
|
||||
return new ChunkPosWrapper(getPlayer().xChunk, getPlayer().zChunk);
|
||||
}
|
||||
|
||||
|
||||
public GameSettings getOptions()
|
||||
{
|
||||
return mc.options;
|
||||
@@ -194,39 +196,43 @@ public class MinecraftWrapper
|
||||
return mc.getModelManager();
|
||||
}
|
||||
|
||||
public ClientWorld getClientLevel()
|
||||
public ClientWorld getClientWorld()
|
||||
{
|
||||
return mc.level;
|
||||
}
|
||||
|
||||
public LevelWrapper getWrappedClientLevel()
|
||||
/**
|
||||
* Attempts to get the ServerWorld for the dimension
|
||||
* the user is currently in.
|
||||
* @returns null if no ServerWorld is available
|
||||
*/
|
||||
public WorldWrapper getWrappedServerWorld()
|
||||
{
|
||||
return LevelWrapper.getLevelWrapper(mc.level);
|
||||
}
|
||||
|
||||
public LevelWrapper getWrappedServerLevel()
|
||||
{
|
||||
|
||||
if (mc.level == null)
|
||||
return null;
|
||||
|
||||
DimensionType dimension = mc.level.dimensionType();
|
||||
IntegratedServer server = mc.getSingleplayerServer();
|
||||
|
||||
if (server == null)
|
||||
return null;
|
||||
|
||||
ServerWorld serverWorld = null;
|
||||
Iterable<ServerWorld> worlds = server.getAllLevels();
|
||||
ServerWorld returnWorld = null;
|
||||
|
||||
for (ServerWorld world : worlds)
|
||||
{
|
||||
if (world.dimensionType() == dimension)
|
||||
{
|
||||
returnWorld = world;
|
||||
serverWorld = world;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return LevelWrapper.getLevelWrapper(returnWorld);
|
||||
return WorldWrapper.getWorldWrapper(serverWorld);
|
||||
}
|
||||
|
||||
public WorldWrapper getWrappedClientWorld()
|
||||
{
|
||||
return WorldWrapper.getWorldWrapper(mc.level);
|
||||
}
|
||||
|
||||
/** Measured in chunks */
|
||||
@@ -285,19 +291,36 @@ public class MinecraftWrapper
|
||||
return mc.levelRenderer;
|
||||
}
|
||||
|
||||
/** Returns all worlds available to the server */
|
||||
public ArrayList<WorldWrapper> getAllServerWorlds()
|
||||
{
|
||||
ArrayList<WorldWrapper> worlds = new ArrayList<WorldWrapper>();
|
||||
|
||||
Iterable<ServerWorld> serverWorlds = mc.getSingleplayerServer().getAllLevels();
|
||||
for (ServerWorld world : serverWorlds)
|
||||
{
|
||||
worlds.add(WorldWrapper.getWorldWrapper(world));
|
||||
}
|
||||
|
||||
return worlds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Crashes Minecraft, displaying the given errorMessage <br> <br>
|
||||
* In the following format: <br>
|
||||
*
|
||||
* The game crashed whilst <strong>errorMessage</strong> <br>
|
||||
* Error: <strong>java.lang.ExceptionClass: exceptionErrorMessage</strong> <br>
|
||||
* Error: <strong>ExceptionClass: exceptionErrorMessage</strong> <br>
|
||||
* Exit Code: -1 <br>
|
||||
*/
|
||||
public void crashMinecraft(String errorMessage, Throwable exception)
|
||||
{
|
||||
ClientProxy.LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
|
||||
ClientApi.LOGGER.error(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...");
|
||||
CrashReport report = new CrashReport(errorMessage, exception);
|
||||
Minecraft.crash(report);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,49 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
|
||||
* licensed under the GNU GPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.lod.wrappers.World;
|
||||
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
|
||||
import net.minecraft.world.biome.BiomeColors;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Cola?
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public class BiomeColorWrapper
|
||||
{
|
||||
|
||||
public static int getGrassColor(LevelWrapper levelWrapper, BlockPosWrapper blockPosWrapper)
|
||||
public static int getGrassColor(WorldWrapper world, BlockPosWrapper blockPos)
|
||||
{
|
||||
return BiomeColors.getAverageGrassColor(levelWrapper.getWorld(), blockPosWrapper.getBlockPos());
|
||||
return BiomeColors.getAverageGrassColor(world.getWorld(), blockPos.getBlockPos());
|
||||
}
|
||||
public static int getWaterColor(LevelWrapper levelWrapper, BlockPosWrapper blockPosWrapper)
|
||||
public static int getWaterColor(WorldWrapper world, BlockPosWrapper blockPos)
|
||||
{
|
||||
|
||||
return BiomeColors.getAverageWaterColor(levelWrapper.getWorld(), blockPosWrapper.getBlockPos());
|
||||
return BiomeColors.getAverageWaterColor(world.getWorld(), blockPos.getBlockPos());
|
||||
}
|
||||
public static int getFoliageColor(LevelWrapper levelWrapper, BlockPosWrapper blockPosWrapper)
|
||||
public static int getFoliageColor(WorldWrapper world, BlockPosWrapper blockPos)
|
||||
{
|
||||
|
||||
return BiomeColors.getAverageFoliageColor(levelWrapper.getWorld(), blockPosWrapper.getBlockPos());
|
||||
return BiomeColors.getAverageFoliageColor(world.getWorld(), blockPos.getBlockPos());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.seibel.lod.wrappers.World;
|
||||
|
||||
import net.minecraft.world.DimensionType;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import net.minecraft.world.DimensionType;
|
||||
|
||||
public class DimensionTypeWrapper
|
||||
{
|
||||
private static final ConcurrentMap<DimensionType, DimensionTypeWrapper> dimensionTypeWrapperMap = new ConcurrentHashMap<>();
|
||||
@@ -34,4 +34,19 @@ public class DimensionTypeWrapper
|
||||
{
|
||||
dimensionTypeWrapperMap.clear();
|
||||
}
|
||||
|
||||
public String getDimensionName()
|
||||
{
|
||||
return dimensionType.effectsLocation().getPath();
|
||||
}
|
||||
|
||||
public boolean hasCeiling()
|
||||
{
|
||||
return dimensionType.hasCeiling();
|
||||
}
|
||||
|
||||
public boolean hasSkyLight()
|
||||
{
|
||||
return dimensionType.hasSkyLight();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
package com.seibel.lod.wrappers.World;
|
||||
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.LightType;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class LevelWrapper
|
||||
{
|
||||
private static final ConcurrentMap<IWorld, LevelWrapper> worldWrapperMap = new ConcurrentHashMap<>();
|
||||
private final IWorld world;
|
||||
|
||||
public LevelWrapper(IWorld world)
|
||||
{
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
|
||||
public static LevelWrapper getLevelWrapper(IWorld world)
|
||||
{
|
||||
//first we check if the biome has already been wrapped
|
||||
if(worldWrapperMap.containsKey(world) && worldWrapperMap.get(world) != null)
|
||||
return worldWrapperMap.get(world);
|
||||
|
||||
|
||||
//if it hasn't been created yet, we create it and save it in the map
|
||||
LevelWrapper levelWrapper = new LevelWrapper(world);
|
||||
worldWrapperMap.put(world, levelWrapper);
|
||||
|
||||
//we return the newly created wrapper
|
||||
return levelWrapper;
|
||||
}
|
||||
|
||||
public static void clearMap()
|
||||
{
|
||||
worldWrapperMap.clear();
|
||||
}
|
||||
|
||||
public DimensionTypeWrapper getDimensionType()
|
||||
{
|
||||
return DimensionTypeWrapper.getDimensionTypeWrapper(world.dimensionType());
|
||||
}
|
||||
|
||||
public int getBlockLight(BlockPosWrapper blockPos)
|
||||
{
|
||||
return world.getBrightness(LightType.BLOCK, blockPos.getBlockPos());
|
||||
}
|
||||
|
||||
public int getSkyLight(BlockPosWrapper blockPos)
|
||||
{
|
||||
return world.getBrightness(LightType.SKY, blockPos.getBlockPos());
|
||||
}
|
||||
|
||||
public BiomeWrapper getBiome(BlockPosWrapper blockPos)
|
||||
{
|
||||
return BiomeWrapper.getBiomeWrapper(world.getBiome(blockPos.getBlockPos()));
|
||||
}
|
||||
|
||||
public IWorld getWorld()
|
||||
{
|
||||
return world;
|
||||
}
|
||||
|
||||
public boolean hasCeiling()
|
||||
{
|
||||
return world.dimensionType().hasCeiling();
|
||||
}
|
||||
|
||||
public boolean hasSkyLight()
|
||||
{
|
||||
return world.dimensionType().hasSkyLight();
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return world == null;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,44 @@
|
||||
package com.seibel.lod.wrappers.World;
|
||||
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
import net.minecraft.world.IWorld;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import com.seibel.lod.enums.WorldType;
|
||||
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
|
||||
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.server.ServerChunkProvider;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author James Seibel
|
||||
* @author ??
|
||||
* @version 11-12-2021
|
||||
*/
|
||||
public class WorldWrapper
|
||||
{
|
||||
private static final ConcurrentMap<IWorld, WorldWrapper> worldWrapperMap = new ConcurrentHashMap<>();
|
||||
private final IWorld world;
|
||||
public final WorldType worldType;
|
||||
|
||||
public WorldWrapper(IWorld world)
|
||||
|
||||
public WorldWrapper(IWorld newWorld)
|
||||
{
|
||||
this.world = world;
|
||||
world = newWorld;
|
||||
|
||||
if (world.getClass() == ServerWorld.class)
|
||||
worldType = WorldType.ServerWorld;
|
||||
else if (world.getClass() == ClientWorld.class)
|
||||
worldType = WorldType.ClientWorld;
|
||||
else
|
||||
worldType = WorldType.Unknown;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static WorldWrapper getWorldWrapper(IWorld world)
|
||||
{
|
||||
//first we check if the biome has already been wrapped
|
||||
@@ -76,4 +98,31 @@ public class WorldWrapper
|
||||
{
|
||||
return world == null;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return world.getHeight();
|
||||
}
|
||||
|
||||
/** @throws UnsupportedOperationException if the WorldWrapper isn't for a ServerWorld */
|
||||
public File getSaveFolder() throws UnsupportedOperationException
|
||||
{
|
||||
if (worldType != WorldType.ServerWorld)
|
||||
throw new UnsupportedOperationException("getSaveFolder can only be called for ServerWorlds.");
|
||||
|
||||
ServerChunkProvider chunkSource = ((ServerWorld) world).getChunkSource();
|
||||
return chunkSource.dataStorage.dataFolder;
|
||||
}
|
||||
|
||||
|
||||
/** @throws UnsupportedOperationException if the WorldWrapper isn't for a ServerWorld */
|
||||
public ServerWorld getServerWorld() throws UnsupportedOperationException
|
||||
{
|
||||
if (worldType != WorldType.ServerWorld)
|
||||
throw new UnsupportedOperationException("getSaveFolder can only be called for ServerWorlds.");
|
||||
|
||||
return (ServerWorld) world;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user