Merge branch 'immersivePortals'

Thanks Acuadragon100!
This commit is contained in:
James Seibel
2026-06-01 07:45:25 -05:00
parent de33cbce2b
commit a94cd91a97
51 changed files with 917 additions and 396 deletions
@@ -77,43 +77,6 @@ public class CleanroomClientProxy implements AbstractModInitializer.IEventProxy
}
//==============//
// world events //
//==============//
@SubscribeEvent
public void clientLevelLoadEvent(WorldEvent.Load event)
{
LOGGER.info("level load");
World level = event.getWorld();
if (!(level instanceof WorldClient clientLevel))
{
return;
}
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel, true);
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
}
@SubscribeEvent
public void clientLevelUnloadEvent(WorldEvent.Unload event)
{
LOGGER.info("level unload");
World level = event.getWorld();
if (!(level instanceof WorldClient clientLevel))
{
return;
}
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
}
//==============//
// chunk events //
//==============//
@@ -26,7 +26,6 @@ import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.GlStateManager;
@@ -61,9 +60,8 @@ public class MixinEntityRenderer
return;
}
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
MinecraftRenderWrapper renderWrapper = (MinecraftRenderWrapper)SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
renderWrapper.setLightmapId(lightmapTexture.getGlTextureId(), clientLevel);
renderWrapper.setLightmapId(lightmapTexture.getGlTextureId());
}
@Inject(at = @At("RETURN"), method = "setupFog")
@@ -0,0 +1,60 @@
package com.seibel.distanthorizons.common.commonMixins;
#if MC_VER > MC_1_12_2
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.modAccessor.AbstractImmersivePortalsAccessorCommon;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.phys.Vec3;
public class MixinImmersivePortalsRenderStatesCommon
{
/**
* Used to access variables that will change when rendering
* different levels with Immersive Portals
* (ie player/camera position level reference)
* but that we only want for the loaded level.
*/
public static void saveVolatileOriginals()
{
Minecraft mc = Minecraft.getInstance();
AbstractImmersivePortalsAccessorCommon.actualLevel = mc.level;
// clear everything if the player is missing
// (ie the world hasn't loaded yet)
if (mc.player == null)
{
AbstractImmersivePortalsAccessorCommon.actualBlockPos = null;
AbstractImmersivePortalsAccessorCommon.actualChunkPos = null;
AbstractImmersivePortalsAccessorCommon.actualCameraPos = null;
return;
}
// player block pos
BlockPos playerBlockPos = mc.player.blockPosition();
AbstractImmersivePortalsAccessorCommon.actualBlockPos = new DhBlockPos(playerBlockPos.getX(), playerBlockPos.getY(), playerBlockPos.getZ());
// player chunk pos
#if MC_VER < MC_1_17_1
ChunkPos playerChunkPos = new ChunkPos(mc.player.blockPosition());
#else
ChunkPos playerChunkPos = mc.player.chunkPosition();
#endif
AbstractImmersivePortalsAccessorCommon.actualChunkPos = McObjectConverter.Convert(playerChunkPos);
// camera pos
#if MC_VER <= MC_1_21_10
Vec3 cameraPos = mc.gameRenderer.getMainCamera().getPosition();
#else
Vec3 cameraPos = mc.gameRenderer.getMainCamera().position();
#endif
AbstractImmersivePortalsAccessorCommon.actualCameraPos = new Vec3d(cameraPos.x(), cameraPos.y(), cameraPos.z());
}
}
#endif
@@ -7,6 +7,7 @@ import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft;
@@ -26,6 +27,7 @@ import net.minecraft.world.level.material.FluidState;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_3
@@ -50,6 +52,11 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else
import net.minecraft.world.level.material.FogType;
import net.minecraft.client.renderer.fog.FogRenderer;
import net.minecraft.client.renderer.fog.FogData;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
#endif
@@ -104,6 +111,15 @@ public class MixinVanillaFogCommon
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
// since DH won't render through immersive portals
// the vanilla fog should be enabled
IImmersivePortalsAccessor immersivePortals = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
if (immersivePortals != null
&& immersivePortals.isRenderingPortal())
{
cancelFog = false;
}
return cancelFog;
}
#if MC_VER <= MC_1_12_2
@@ -124,4 +140,6 @@ public class MixinVanillaFogCommon
return cameraNotInFluid;
}
}
@@ -1,5 +1,6 @@
package com.seibel.distanthorizons.common.wrappers.level;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
@@ -8,17 +9,27 @@ import net.minecraft.client.multiplayer.WorldClient;
#else
import net.minecraft.client.multiplayer.ClientLevel;
#endif
import net.minecraft.client.Minecraft;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
public class KeyedClientLevelManager implements IKeyedClientLevelManager
{
public static final KeyedClientLevelManager INSTANCE = new KeyedClientLevelManager();
/** This is set and managed by the ClientApi for servers with support for DH. */
@Nullable
private IServerKeyedClientLevel serverKeyedLevel = null;
/** Stores the server-provided keys indexed by dimension name for persistence. */
private final Map<String, KeyInfo> keysByDimensionName = new ConcurrentHashMap<>();
/** Cache for already keyed level wrappers to maintain object identity. */
private final Map<#if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif, IServerKeyedClientLevel>
keyedLevelsCache = Collections.synchronizedMap(new WeakHashMap<>());
/** Allows to keep level manager enabled between loading different keyed levels */
private boolean enabled = false;
private volatile boolean enabled = false;
@@ -41,32 +52,140 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
@Override
@Nullable
public IServerKeyedClientLevel getServerKeyedLevel() { return this.serverKeyedLevel; }
public IServerKeyedClientLevel getServerKeyedLevel()
{
#if MC_VER > MC_1_12_2
return this.getServerKeyedLevel(Minecraft.getInstance().level);
#else
return this.getServerKeyedLevel(Minecraft.getMinecraft().world);
#endif
}
@Nullable
public IServerKeyedClientLevel getServerKeyedLevel(@Nullable #if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif level)
{
if (level == null)
{
return null;
}
// We synchronize on the cache map to ensure atomicity of the lookup-and-populate sequence.
// This prevents multiple threads from creating duplicate wrappers for the same level.
synchronized (this.keyedLevelsCache)
{
// Check the cache first
IServerKeyedClientLevel cached = this.keyedLevelsCache.get(level);
if (cached != null)
{
return cached;
}
// Determine the dimension name for this level
// We use bypassLevelKeyManager=true to avoid recursion back into this manager
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level, true);
if (wrappedLevel == null)
{
return null;
}
String dimensionName = wrappedLevel.getDimensionName();
KeyInfo info = this.keysByDimensionName.get(dimensionName);
if (info == null)
{
return null;
}
// Create and cache a new keyed wrapper
IServerKeyedClientLevel keyedLevel = new ServerKeyedClientLevelWrapper(level, info.serverKey, info.levelKey);
this.keyedLevelsCache.put(level, keyedLevel);
return keyedLevel;
}
}
@Override
public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String serverKey, String levelKey)
{
IServerKeyedClientLevel keyedLevel;
#if MC_VER <= MC_1_12_2
keyedLevel = new ServerKeyedClientLevelWrapper((WorldClient) clientLevel.getWrappedMcObject(), serverKey, levelKey);
#else
keyedLevel = new ServerKeyedClientLevelWrapper((ClientLevel) clientLevel.getWrappedMcObject(), serverKey, levelKey);
#endif
// 1. Determine the target dimension name
String targetDimensionName = clientLevel.getDimensionName();
int separatorIndex = levelKey.lastIndexOf("@");
if (separatorIndex != -1)
{
targetDimensionName = levelKey.substring(separatorIndex + 1);
}
this.serverKeyedLevel = keyedLevel;
final String finalTargetDimensionName = targetDimensionName;
// 2. Store the key for this dimension
this.keysByDimensionName.put(finalTargetDimensionName, new KeyInfo(serverKey, levelKey));
this.enabled = true;
return keyedLevel;
// 3. Clear the cache for this dimension to ensure new wrappers are created with the new key
// (though in practice keys shouldn't change mid-session)
//
// We synchronize manually on the map to ensure atomicity of the compound removal operation
// and to prevent race conditions or deadlocks with other threads accessing the map.
// We avoid calling ClientLevelWrapper.getWrapper() inside the lock to prevent circular lock dependencies.
synchronized (this.keyedLevelsCache)
{
this.keyedLevelsCache.keySet().removeIf(level ->
{
#if MC_VER <= MC_1_12_2
String levelDim = level.provider.getDimensionType().getName() + ":" + level.provider.getDimension();
#elif MC_VER <= MC_1_21_10
String levelDim = level.dimension().location().toString();
#else
String levelDim = level.dimension().identifier().toString();
#endif
return levelDim.equals(finalTargetDimensionName);
});
}
// 4. Return the keyed wrapper for whatever level the core passed us,
// but only if it matches the dimension we just keyed.
return this.getServerKeyedLevel((#if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif) clientLevel.getWrappedMcObject());
}
@Override
public void clearKeyedLevel() { this.serverKeyedLevel = null; }
public void clearKeyedLevel()
{
synchronized (this.keyedLevelsCache)
{
this.keyedLevelsCache.clear();
this.keysByDimensionName.clear();
}
}
@Override
public boolean isEnabled() { return this.enabled; }
@Override
public void disable() { this.enabled = false; }
public void disable()
{
this.enabled = false;
this.clearKeyedLevel();
}
//================//
// helper classes //
//================//
//region
private static class KeyInfo
{
public final String serverKey;
public final String levelKey;
public KeyInfo(String serverKey, String levelKey)
{
this.serverKey = serverKey;
this.levelKey = levelKey;
}
}
//endregion
}
@@ -0,0 +1,65 @@
package com.seibel.distanthorizons.common.wrappers.minecraft;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_12_2
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
#else
import net.minecraft.world.WorldServer;
#endif
#if MC_VER <= MC_1_12_2
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation;
#else
import net.minecraft.resources.Identifier;
#endif
#if MC_VER > MC_1_19_2
import net.minecraft.core.registries.Registries;
#elif MC_VER > MC_1_12_2
import net.minecraft.core.Registry;
#endif
public abstract class AbstractMinecraftSharedWrapper implements IMinecraftSharedWrapper
{
@Nullable
protected ResourceKey<Level> deserializeDimensionResourceKey(String dimensionResourceLocation)
{
#if MC_VER <= MC_1_12_2
int dimensionID;
try
{
dimensionID = Integer.parseInt(dimensionResourceLocation.substring(dimensionResourceLocation.indexOf(":")+1));
}
catch (NumberFormatException ignored)
{
return null;
}
#else
#if MC_VER <= MC_1_21_10
ResourceLocation dimResourceLocation = ResourceLocation.tryParse(dimensionResourceLocation);
#else
Identifier dimResourceLocation = Identifier.tryParse(dimensionResourceLocation);
#endif
if (dimResourceLocation == null)
{
return null;
}
#if MC_VER > MC_1_19_2
ResourceKey<Level> dimensionKey = ResourceKey.create(Registries.DIMENSION, dimResourceLocation);
#else
ResourceKey<Level> dimensionKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, dimResourceLocation);
#endif
#endif
return dimensionKey;
}
}
@@ -26,9 +26,13 @@ import com.mojang.blaze3d.platform.Window;
#endif
import com.seibel.distanthorizons.common.wrappers.gui.NativeDialogUtil;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
@@ -48,14 +52,20 @@ import net.minecraft.profiler.Profiler;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.DimensionType;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
#else
import net.minecraft.CrashReport;
import net.minecraft.client.CloudStatus;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
#endif
import org.jetbrains.annotations.Nullable;
@@ -74,13 +84,25 @@ import net.minecraft.client.GraphicsStatus;
#else
#endif
#if MC_VER <= MC_1_12_2
import net.minecraft.util.ResourceLocation;
#elif MC_VER <= MC_1_21_10
#else
import net.minecraft.resources.Identifier;
#endif
#if MC_VER > MC_1_19_2
import net.minecraft.core.registries.Registries;
#elif MC_VER > MC_1_12_2
#endif
/**
* A singleton that wraps the Minecraft object.
*
* @author James Seibel
*/
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
public class MinecraftClientWrapper extends AbstractMinecraftSharedWrapper implements IMinecraftClientWrapper
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -95,6 +117,12 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
private ProfilerWrapper profilerWrapper;
/** Delayed accessing is necessary since this object will be created before the mod accessors are bound. */
private static class DelayedAccessors
{
public static final IImmersivePortalsAccessor IMMERSIVE_PORTALS = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
}
//======================//
@@ -232,6 +260,15 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
return new DhBlockPos(0, 0, 0);
}
if (DelayedAccessors.IMMERSIVE_PORTALS != null)
{
DhBlockPos pos = DelayedAccessors.IMMERSIVE_PORTALS.getActualPlayerBlockPos();
if (pos != null)
{
return pos;
}
}
#if MC_VER <= MC_1_12_2
BlockPos playerPos = player.getPosition();
#else
@@ -253,7 +290,16 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
return new DhChunkPos(0, 0);
}
#if MC_VER <= MC_1_12_2
if (DelayedAccessors.IMMERSIVE_PORTALS != null)
{
DhChunkPos pos = DelayedAccessors.IMMERSIVE_PORTALS.getActualPlayerChunkPos();
if (pos != null)
{
return pos;
}
}
#if MC_VER <= MC_1_12_2
ChunkPos playerPos = new ChunkPos(player.getPosition());
#elif MC_VER < MC_1_17_1
ChunkPos playerPos = new ChunkPos(player.blockPosition());
@@ -285,6 +331,16 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
@Nullable
public IClientLevelWrapper getWrappedClientLevel(boolean bypassLevelKeyManager)
{
if (!bypassLevelKeyManager
&& DelayedAccessors.IMMERSIVE_PORTALS != null)
{
IClientLevelWrapper level = DelayedAccessors.IMMERSIVE_PORTALS.getActualClientLevelWrapper();
if (level != null)
{
return level;
}
}
#if MC_VER <= MC_1_12_2
WorldClient level = MINECRAFT.world;
#else
@@ -583,6 +639,25 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
}
}
@Nullable
@Override
public IServerLevelWrapper getWrappedServerLevelWithDimensionResourceLocation(String dimensionResourceLocation)
{
if (!this.hasSinglePlayerServer())
{
return null;
}
ResourceKey<Level> dimensionKey = this.deserializeDimensionResourceKey(dimensionResourceLocation);
#if MC_VER <= MC_1_12_2
WorldServer mcLevel = MINECRAFT.getIntegratedServer().getWorld(dimensionKey);
#else
ServerLevel mcLevel = MINECRAFT.getSingleplayerServer().getLevel(dimensionKey);
#endif
return ServerLevelWrapper.getWrapper(mcLevel);
}
//endregion
@@ -22,6 +22,8 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
import java.awt.Color;
import java.util.concurrent.ConcurrentHashMap;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_12_2
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.NativeImage;
@@ -30,20 +32,24 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingApi;
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
#if MC_VER < MC_1_17_1
#elif MC_VER < MC_1_21_3
import net.minecraft.client.renderer.FogRenderer;
#elif MC_VER < MC_1_21_6
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import net.minecraft.client.renderer.FogRenderer;
import com.mojang.blaze3d.systems.RenderSystem;
#else
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import net.minecraft.client.renderer.fog.FogData;
import net.minecraft.client.renderer.fog.FogRenderer;
#endif
@@ -60,6 +66,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
#if MC_VER <= MC_1_12_2
@@ -101,6 +108,7 @@ import com.mojang.blaze3d.opengl.GlTexture;
#else
import net.minecraft.world.attribute.EnvironmentAttributes;
import com.mojang.blaze3d.textures.GpuTexture;
import org.joml.Vector4f;
#endif
/**
@@ -112,6 +120,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -121,6 +130,12 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
private static final Minecraft MC = Minecraft.getInstance();
#endif
/** Delayed accessing is necessary since this object will be created before the mod accessors are bound. */
private static class DelayedAccessors
{
public static final IImmersivePortalsAccessor IMMERSIVE_PORTALS = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
}
/**
* In the case of immersive portals multiple levels may be active at once, causing conflicting lightmaps. <br>
* Requiring the use of multiple {@link LightMapWrapper}.
@@ -202,6 +217,12 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
@Override
public Vec3d getCameraExactPosition()
{
if (DelayedAccessors.IMMERSIVE_PORTALS != null)
{
Vec3d cameraPos = DelayedAccessors.IMMERSIVE_PORTALS.getActualCameraPos();
if (cameraPos != null) return cameraPos;
}
#if MC_VER <= MC_1_12_2
RenderManager rm = MC.getRenderManager();
return new Vec3d(rm.viewerPosX, rm.viewerPosY, rm.viewerPosZ);
@@ -571,9 +592,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
#endif
}
@Override
public ILightMapWrapper getLightmapWrapper(@NotNull ILevelWrapper level) { return this.lightmapByDimensionType.get(level.getDimensionType()); }
@Override
public boolean isFogStateSpecial()
{
@@ -598,94 +616,90 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
#endif
}
//==========//
// lightmap //
//==========//
//region
@Override
public ILightMapWrapper getLightmapWrapper(@NotNull ILevelWrapper level) { return this.lightmapByDimensionType.get(level.getDimensionType()); }
/**
* It's better to use {@link MinecraftRenderWrapper#setLightmapId(int, IClientLevelWrapper)} if possible,
* It's better to use {@link MinecraftRenderWrapper#setLightmapId(int)} if possible,
* however old MC versions don't support it.
*/
#if MC_VER > MC_1_12_2
public void updateLightmap(NativeImage lightPixels, IClientLevelWrapper level)
public void updateLightmap(NativeImage lightPixels)
{
IClientLevelWrapper clientLevel = getLightmapClientLevelWrapper();
if (clientLevel == null)
{
return;
}
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
// object for the same MC level and/or the same hash,
// so this will have to do for now
IDimensionTypeWrapper dimensionType = level.getDimensionType();
IDimensionTypeWrapper dimensionType = clientLevel.getDimensionType();
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
wrapper.uploadLightmap(lightPixels);
}
#endif
public void setLightmapId(int tetxureId, IClientLevelWrapper level)
public void setLightmapId(int textureId)
{
IClientLevelWrapper clientLevel = getLightmapClientLevelWrapper();
if (clientLevel == null)
{
return;
}
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
// object for the same MC level and/or the same hash,
// so this will have to do for now
IDimensionTypeWrapper dimensionType = level.getDimensionType();
IDimensionTypeWrapper dimensionType = clientLevel.getDimensionType();
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
wrapper.setLightmapId(tetxureId);
wrapper.setLightmapId(textureId);
}
#if MC_VER <= MC_1_21_10
#else
public void setLightmapGpuTexture(GpuTexture gpuTexture, IClientLevelWrapper level)
public void setLightmapGpuTexture(GpuTexture gpuTexture)
{
IClientLevelWrapper clientLevel = getLightmapClientLevelWrapper();
if (clientLevel == null)
{
return;
}
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
// object for the same MC level and/or the same hash,
// so this will have to do for now
IDimensionTypeWrapper dimensionType = level.getDimensionType();
IDimensionTypeWrapper dimensionType = clientLevel.getDimensionType();
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
wrapper.setLightmapGpuTexture(gpuTexture);
}
#endif
@Override
public float getShade(EDhDirection lodDirection)
/** special logic is necessary in order for Immersive Portals to work correctly */
private static @Nullable IClientLevelWrapper getLightmapClientLevelWrapper()
{
EDhApiLodShading lodShading = Config.Client.Advanced.Graphics.Quality.lodShading.get();
switch (lodShading)
IClientLevelWrapper clientLevel = ClientApi.RENDER_STATE.clientLevelWrapper;
if (clientLevel == null)
{
default:
case AUTO:
#if MC_VER <= MC_1_12_2
// 1.12.2 has no getShade, fall through to ENABLED
#else
if (MC.level != null)
{
Direction mcDir = McObjectConverter.Convert(lodDirection);
#if MC_VER <= MC_1_21_11
return MC.level.getShade(mcDir, true);
#else
return MC.level.cardinalLighting().byFace(mcDir);
#endif
}
else
{
return 0.0f;
}
#endif
case ENABLED:
switch (lodDirection)
{
case DOWN:
return 0.5F;
default:
case UP:
return 1.0F;
case NORTH:
case SOUTH:
return 0.8F;
case WEST:
case EAST:
return 0.6F;
}
case DISABLED:
return 1.0F;
clientLevel = MC_CLIENT.getWrappedClientLevel();
}
return clientLevel;
}
//endregion
}
@@ -1,12 +1,34 @@
package com.seibel.distanthorizons.common.wrappers.minecraft;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import net.minecraft.server.dedicated.DedicatedServer;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_12_2
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
#else
import net.minecraft.world.WorldServer;
#endif
#if MC_VER <= MC_1_12_2
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation;
#else
import net.minecraft.resources.Identifier;
#endif
#if MC_VER > MC_1_19_2
import net.minecraft.core.registries.Registries;
#elif MC_VER > MC_1_12_2
import net.minecraft.core.Registry;
#endif
import java.io.File;
public class MinecraftServerWrapper implements IMinecraftSharedWrapper
public class MinecraftServerWrapper extends AbstractMinecraftSharedWrapper
{
public static final MinecraftServerWrapper INSTANCE = new MinecraftServerWrapper();
@@ -64,5 +86,23 @@ public class MinecraftServerWrapper implements IMinecraftSharedWrapper
}
@Nullable
@Override
public IServerLevelWrapper getWrappedServerLevelWithDimensionResourceLocation(String dimensionResourceLocation)
{
if (this.dedicatedServer == null)
{
throw new IllegalStateException("Trying to get the server mcLevel before dedicated server completed initialization!");
}
ResourceKey<Level> dimensionKey = this.deserializeDimensionResourceKey(dimensionResourceLocation);
#if MC_VER <= MC_1_12_2
WorldServer mcLevel = dedicatedServer.getWorld(dimensionKey);
#else
ServerLevel mcLevel = dedicatedServer.getLevel(dimensionKey);
#endif
return ServerLevelWrapper.getWrapper(mcLevel);
}
}
@@ -0,0 +1,76 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL 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 Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.common.wrappers.modAccessor;
#if MC_VER <= MC_1_12_2
public abstract class AbstractImmersivePortalsAccessorCommon {}
#else
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.multiplayer.ClientLevel;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_19_2
import org.joml.Matrix4f;
#else
#endif
#if MC_VER < MC_1_17_1
import java.lang.reflect.Field;
#endif
public abstract class AbstractImmersivePortalsAccessorCommon extends AbstractImmersivePortalsAccessor
{
// We don't use the fields in RenderStates because they are not volatile.
@Nullable
public static volatile ClientLevel actualLevel;
@Nullable
public static volatile DhBlockPos actualBlockPos;
@Nullable
public static volatile DhChunkPos actualChunkPos;
@Nullable
public static volatile Vec3d actualCameraPos;
@Override
@Nullable
public DhBlockPos getActualPlayerBlockPos() { return actualBlockPos; }
@Override
@Nullable
public DhChunkPos getActualPlayerChunkPos() { return actualChunkPos; }
@Override
@Nullable
public IClientLevelWrapper getActualClientLevelWrapper() { return ClientLevelWrapper.getWrapper(actualLevel, false); }
@Override
@Nullable
public Vec3d getActualCameraPos() { return actualCameraPos; }
}
#endif
@@ -1,5 +1,6 @@
package com.seibel.distanthorizons.common.wrappers.world;
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBiomeWrapper;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
@@ -9,13 +10,20 @@ import com.seibel.distanthorizons.api.objects.data.IDhApiFullDataSource;
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
import com.seibel.distanthorizons.common.wrappers.block.ClientBlockStateColorCache;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.level.KeyedClientLevelManager;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.level.*;
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
import com.seibel.distanthorizons.core.util.TimerUtil;
import com.seibel.distanthorizons.core.world.AbstractDhWorld;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
@@ -32,6 +40,7 @@ import net.minecraft.block.state.IBlockState;
#else
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
#endif
@@ -44,9 +53,7 @@ import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@@ -80,7 +87,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private static final Map<
#if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif,
WeakReference<ClientLevelWrapper>> LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL = Collections.synchronizedMap(new WeakHashMap<>());
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
private static final KeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = KeyedClientLevelManager.INSTANCE;
#if MC_VER <= MC_1_12_2
private static final Minecraft MINECRAFT = Minecraft.getMinecraft();
@@ -90,6 +97,12 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private static final ThreadLocal<DhBlockPosMutable> MUTABLE_BLOCK_POS_THREAD_LOCAL = ThreadLocal.withInitial(DhBlockPosMutable::new);
private static final Timer CLIENT_CLEANUP_TIMER = TimerUtil.CreateTimer("ClientLevelTickCleanup");
private static final TimerTask CLIENT_CLEANUP_TASK = TimerUtil.createTimerTask(ClientLevelWrapper::tickCleanup);
/** how long in milliseconds can a level be unused before it's automatically unloaded */
private static final long INACTIVE_TIME_BEFORE_UNLOADED_IN_MS = 30 * 1000;
#if MC_VER <= MC_1_12_2
@@ -110,8 +123,9 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private boolean cloudColorFailLogged = false;
private BlockStateWrapper dirtBlockWrapper;
private IDhLevel dhLevel;
private volatile BlockStateWrapper dirtBlockWrapper;
private volatile IDhLevel dhLevel;
private volatile long lastAccessTime = System.currentTimeMillis();
@@ -126,11 +140,88 @@ public class ClientLevelWrapper implements IClientLevelWrapper
//==================//
// instance methods //
//==================//
//======================//
// inactivity unloading //
//======================//
//region
@Override
public synchronized void markAccessed() { this.lastAccessTime = System.currentTimeMillis(); }
public synchronized long getLastAccessTime() { return this.lastAccessTime; }
static
{
// fire 20 times per second (i.e. 50ms interval)
CLIENT_CLEANUP_TIMER.scheduleAtFixedRate(CLIENT_CLEANUP_TASK, 0, 1000 / 20);
}
public static void tickCleanup()
{
#if MC_VER <= MC_1_12_2
WorldClient clientLevel = MINECRAFT.world;
#else
ClientLevel clientLevel = MINECRAFT.level;
#endif
if (clientLevel == null)
{
return;
}
long currentTime = System.currentTimeMillis();
ArrayList<ClientLevelWrapper> levelsToUnload = new ArrayList<>();
synchronized(LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL) // should only be run on one thread at a time, but just in case
{
for (WeakReference<ClientLevelWrapper> ref : LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.values())
{
ClientLevelWrapper levelWrapper = ref.get();
if (levelWrapper != null
&& levelWrapper.level != clientLevel)
{
// We use the synchronized getter to prevent race conditions with markAccessed()
long inactiveTimeMs = currentTime - levelWrapper.getLastAccessTime();
if (inactiveTimeMs > INACTIVE_TIME_BEFORE_UNLOADED_IN_MS)
{
levelsToUnload.add(levelWrapper);
}
}
}
}
for (ClientLevelWrapper wrapper : levelsToUnload)
{
// Re-verify all conditions inside a synchronized block on the wrapper
// to ensure atomicity with respect to markAccessed()
synchronized(wrapper)
{
long inactiveTimeMs = currentTime - wrapper.getLastAccessTime();
if (wrapper.level != clientLevel
&& inactiveTimeMs > INACTIVE_TIME_BEFORE_UNLOADED_IN_MS)
{
LOGGER.debug("Unloading level [" + wrapper.getDhIdentifier() + "] due to inactivity");
wrapper.tryUnloadFromWorld();
}
}
}
}
//endregion
//================//
// level handling //
//================//
//region
@Override
public void setDhLevel(IDhLevel dhLevel) { this.dhLevel = dhLevel; }
@Override
public IDhLevel getDhLevel() { return this.dhLevel; }
/**
* can be used when speed is important and the same level is likely to be passed in,
* IE rendering.
@@ -140,9 +231,13 @@ public class ClientLevelWrapper implements IClientLevelWrapper
@Nullable IClientLevelWrapper levelWrapper,
@NotNull #if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif level)
{
if (KEYED_CLIENT_LEVEL_MANAGER.isEnabled() && KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel() != levelWrapper)
if (KEYED_CLIENT_LEVEL_MANAGER.isEnabled())
{
return getWrapper(level);
IServerKeyedClientLevel keyedLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(level);
if (keyedLevel != levelWrapper)
{
return getWrapper(level);
}
}
ClientLevelWrapper clientLevelWrapper = (ClientLevelWrapper)levelWrapper;
@@ -172,9 +267,28 @@ public class ClientLevelWrapper implements IClientLevelWrapper
}
// used if the client is connected to a server that defines the currently loaded level
IServerKeyedClientLevel overrideLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel();
IServerKeyedClientLevel overrideLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(level);
if (overrideLevel != null)
{
// if the currently loaded level wrapper doesn't match what's incoming, unload it
WeakReference<ClientLevelWrapper> levelRef = LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.get(level);
if (levelRef != null
&& levelRef.get() != overrideLevel)
{
ClientLevelWrapper levelWrapper = levelRef.get();
if (levelWrapper != null)
{
levelWrapper.tryUnloadFromWorld();
}
levelRef = null;
}
if (levelRef == null
&& overrideLevel instanceof ClientLevelWrapper)
{
LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.put(level, new WeakReference<>((ClientLevelWrapper) overrideLevel));
}
return overrideLevel;
}
}
@@ -337,7 +451,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
}
#if MC_VER <= MC_1_12_2
this.dimensionName = this.level.provider.getDimensionType().getName();
this.dimensionName = this.level.provider.getDimensionType().getName() + ":" + this.level.provider.getDimension();
#elif MC_VER <= MC_1_21_10
this.dimensionName = this.level.dimension().location().toString();
#else
@@ -443,6 +557,15 @@ public class ClientLevelWrapper implements IClientLevelWrapper
@Override
public #if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif getWrappedMcObject() { return this.level; }
private void tryUnloadFromWorld()
{
AbstractDhWorld world = SharedApi.getAbstractDhWorld();
if (world == null
|| !world.unloadLevel(this))
{
this.onUnload();
}
}
@Override
public void onUnload()
{
@@ -504,16 +627,11 @@ public class ClientLevelWrapper implements IClientLevelWrapper
//===================//
// generic rendering //
//===================//
//===========//
// rendering //
//===========//
//region
@Override
public void setDhLevel(IDhLevel dhLevel) { this.dhLevel = dhLevel; }
@Override
public IDhLevel getDhLevel() { return this.dhLevel; }
@Override
public IDhApiCustomRenderRegister getRenderRegister()
{
@@ -604,6 +722,45 @@ public class ClientLevelWrapper implements IClientLevelWrapper
#endif
}
@Override
public float getShade(EDhDirection lodDirection)
{
EDhApiLodShading lodShading = Config.Client.Advanced.Graphics.Quality.lodShading.get();
switch (lodShading)
{
default:
case AUTO:
#if MC_VER <= MC_1_12_2
// 1.12.2 level doesn't have a getShade method, fall through to ENABLED
#else
Direction mcDir = McObjectConverter.Convert(lodDirection);
#if MC_VER <= MC_1_21_11
return this.level.getShade(mcDir, true);
#else
return this.level.cardinalLighting().byFace(mcDir);
#endif
#endif
case ENABLED:
switch (lodDirection)
{
case DOWN:
return 0.5F;
default:
case UP:
return 1.0F;
case NORTH:
case SOUTH:
return 0.8F;
case WEST:
case EAST:
return 0.6F;
}
case DISABLED:
return 1.0F;
}
}
//endregion
@@ -210,7 +210,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
public String getDimensionName()
{
#if MC_VER <= MC_1_12_2
return this.level.provider.getDimensionType().getName();
return this.level.provider.getDimensionType().getName() + ":" + this.level.provider.getDimension();
#elif MC_VER <= MC_1_21_10
return this.level.dimension().location().toString();
#else
+1 -22
View File
@@ -46,28 +46,7 @@ dependencies {
addMod("com.github.quiqueck:BCLib:${rootProject.bclib_version}", rootProject.enable_bclib)
// Canvas
addMod("io.vram:canvas-fabric-${rootProject.canvas_version}", rootProject.enable_canvas)
// Immersive Portals
if (rootProject.enable_immersive_portals == "1") {
modCompileOnly("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${rootProject.immersive_portals_version}")
}
else if (rootProject.enable_immersive_portals == "2") {
modImplementation ("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("com.github.iPortalTeam.ImmersivePortalsMod:q_misc_util:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("com.github.iPortalTeam.ImmersivePortalsMod:build:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
api("com.github.LlamaLad7:MixinExtras:0.2.0-beta.4")
annotationProcessor("com.github.LlamaLad7:MixinExtras:0.2.0-beta.4")
}
addMod("io.vram:canvas-fabric-${project.canvas_version}", rootProject.enable_canvas)
}
@@ -116,6 +116,7 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
this.tryCreateModCompatAccessor("bclib", IBCLibAccessor.class, BCLibAccessor::new);
this.tryCreateModCompatAccessor("c2me", IC2meAccessor.class, C2meAccessor::new);
this.tryCreateModCompatAccessor("imm_ptl_core", IImmersivePortalsAccessor.class, ImmersivePortalsAccessorFabric::new);
#if MC_VER >= MC_1_19_4
// 1.19.4 is the lowest version Iris supports DH
this.tryCreateModCompatAccessor("iris", IIrisAccessor.class, IrisAccessor::new);
@@ -31,10 +31,9 @@ public class MixinClientPacketListener
@Inject(method = "handleLogin", at = @At("RETURN"))
void onHandleLoginEnd(CallbackInfo ci)
{
ClientApi.INSTANCE.onClientOnlyConnected();
ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(this.level, true));
ClientApi.INSTANCE.onClientOnlyConnected();
}
#if MC_VER < MC_1_19_4
@Inject(method = "cleanup", at = @At("HEAD"))
#else
@@ -61,11 +60,12 @@ public class MixinClientPacketListener
return;
}
// Important to get the level from the chunk because the client level might be different if Immersive Portals is present.
ClientLevel clientLevel = (ClientLevel) chunk.getLevel();
executor.execute(() ->
{
IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper((ClientLevel) this.level);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, clientLevel), clientLevel);
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, clientLevelWrapper), clientLevelWrapper);
});
}
@@ -0,0 +1,23 @@
package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.MixinImmersivePortalsRenderStatesCommon;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Pseudo
#if MC_VER > MC_1_16_5
@Mixin(targets = "qouteall.imm_ptl.core.render.context_management.RenderStates")
#else
@Mixin(targets = "com.qouteall.immersive_portals.render.context_management.RenderStates")
#endif
public class MixinImmersivePortalsRenderStates
{
@Inject(method = "updatePreRenderInfo", at = @At("HEAD"))
private static void preRender(CallbackInfo ci)
{ MixinImmersivePortalsRenderStatesCommon.saveVolatileOriginals(); }
}
@@ -174,8 +174,6 @@ public class MixinLevelRenderer
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
#if MC_VER < MC_1_21_6
if (renderType.equals(RenderType.translucent()))
{
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
@@ -85,18 +86,6 @@ public class MixinLightTexture
public void render(LightmapRenderState renderState, CallbackInfo ci)
#endif
{
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (mc == null)
{
return;
}
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
if (clientLevel == null)
{
return;
}
// lazy initialization to make sure we don't call this too early
if (this.renderWrapper == null)
{
@@ -105,29 +94,29 @@ public class MixinLightTexture
#if MC_VER < MC_1_21_3
this.renderWrapper.updateLightmap(this.lightPixels, clientLevel);
this.renderWrapper.updateLightmap(this.lightPixels);
#elif MC_VER < MC_1_21_5
this.renderWrapper.setLightmapId(this.target.getColorTextureId(), clientLevel);
this.renderWrapper.setLightmapId(this.target.getColorTextureId());
#elif MC_VER <= MC_1_21_10
GlTexture glTexture = (GlTexture) this.texture;
this.renderWrapper.setLightmapId(glTexture.glId(), clientLevel);
this.renderWrapper.setLightmapId(glTexture.glId());
#elif MC_VER <= MC_26_1_2
// both options are available since the renderer can be changed to either Blaze3D or OpenGL
GlTexture glTexture = (GlTexture) this.texture;
this.renderWrapper.setLightmapId(glTexture.glId(), clientLevel);
this.renderWrapper.setLightmapId(glTexture.glId());
this.renderWrapper.setLightmapGpuTexture(this.texture, clientLevel);
this.renderWrapper.setLightmapGpuTexture(this.texture);
#else
// this will only be used when using native GL rendering
if (this.texture instanceof GlTexture)
{
GlTexture glTexture = (GlTexture) this.texture;
this.renderWrapper.setLightmapId(glTexture.glId(), clientLevel);
this.renderWrapper.setLightmapId(glTexture.glId());
}
// this will be used for Blaze3D OpenGL and Vulkan
this.renderWrapper.setLightmapGpuTexture(this.texture, clientLevel);
this.renderWrapper.setLightmapGpuTexture(this.texture);
#endif
}
@@ -3,8 +3,6 @@ package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
import com.seibel.distanthorizons.common.commonMixins.DhUpdateScreenBase;
import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.jar.installer.GitlabGetter;
@@ -107,22 +105,6 @@ public abstract class MixinMinecraft
}
#endif
@Inject(at = @At("HEAD"), method = "updateLevelInEngines")
public void updateLevelInEngines(ClientLevel level, CallbackInfo ci)
{
if (this.lastLevel != null && level != this.lastLevel)
{
ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(this.lastLevel));
}
if (level != null)
{
ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(level, true));
}
this.lastLevel = level;
}
@Inject(at = @At("HEAD"), method = "close()V")
public void close(CallbackInfo ci) { SelfUpdater.onClose(); }
@@ -0,0 +1,27 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL 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 Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.fabric.wrappers.modAccessor;
import com.seibel.distanthorizons.common.wrappers.modAccessor.AbstractImmersivePortalsAccessorCommon;
public class ImmersivePortalsAccessorFabric extends AbstractImmersivePortalsAccessorCommon
{
}
@@ -106,60 +106,6 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
}
//==============//
// world events //
//==============//
@SubscribeEvent
#if MC_VER < MC_1_19_2
public void clientLevelLoadEvent(WorldEvent.Load event)
#else
public void clientLevelLoadEvent(LevelEvent.Load event)
#endif
{
LOGGER.info("level load");
#if MC_VER < MC_1_19_2
LevelAccessor level = event.getWorld();
#else
LevelAccessor level = event.getLevel();
#endif
if (!(level instanceof ClientLevel))
{
return;
}
ClientLevel clientLevel = (ClientLevel) level;
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel, true);
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
}
@SubscribeEvent
#if MC_VER < MC_1_19_2
public void clientLevelUnloadEvent(WorldEvent.Unload event)
#else
public void clientLevelUnloadEvent(LevelEvent.Unload event)
#endif
{
LOGGER.info("level unload");
#if MC_VER < MC_1_19_2
LevelAccessor level = event.getWorld();
#else
LevelAccessor level = event.getLevel();
#endif
if (!(level instanceof ClientLevel))
{
return;
}
ClientLevel clientLevel = (ClientLevel) level;
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
}
//==============//
// chunk events //
//==============//
@@ -22,13 +22,13 @@ package com.seibel.distanthorizons.forge;
import com.mojang.brigadier.CommandDispatcher;
import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.distanthorizons.forge.wrappers.modAccessor.ImmersivePortalsAccessorForge;
import com.seibel.distanthorizons.forge.wrappers.modAccessor.ModChecker;
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OptifineAccessor;
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OculusAccessor;
@@ -104,6 +104,18 @@ public class ForgeMain extends AbstractModInitializer
{
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
this.tryCreateModCompatAccessor("oculus", IIrisAccessor.class, OculusAccessor::new);
IModChecker modChecker = SingletonInjector.INSTANCE.get(IModChecker.class);
// We ideally want to detect imm_ptl_core, but 1.16.5 doesn't provide that mod id.
if (modChecker.isModLoaded("imm_ptl_core")
|| modChecker.isModLoaded("immersive_portals"))
{
ModAccessorInjector.INSTANCE.bind(IImmersivePortalsAccessor.class, new ImmersivePortalsAccessorForge());
}
else
{
LOGGER.debug("Skipping mod compatibility accessor for: Immersive Portals");
}
#if MC_VER < MC_1_17_1
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
@@ -45,15 +45,7 @@ public class MixinFogRenderer
remap = #if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
{
#if MC_VER < MC_1_21_6
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera, fogMode);
#elif MC_VER < MC_1_21_6
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera);
#else
boolean cancelFog = MixinVanillaFogCommon.cancelFog();
#endif
if (cancelFog)
if (MixinVanillaFogCommon.cancelFog(camera, fogMode))
{
#if MC_VER < MC_1_17_1
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
@@ -0,0 +1,23 @@
package com.seibel.distanthorizons.forge.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.MixinImmersivePortalsRenderStatesCommon;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Pseudo
#if MC_VER > MC_1_16_5
@Mixin(targets = "qouteall.imm_ptl.core.render.context_management.RenderStates")
#else
@Mixin(targets = "com.qouteall.immersive_portals.render.context_management.RenderStates")
#endif
public class MixinImmersivePortalsRenderStates
{
@Inject(method = "updatePreRenderInfo", at = @At("HEAD"))
private static void preRender(CallbackInfo ci)
{ MixinImmersivePortalsRenderStatesCommon.saveVolatileOriginals(); }
}
@@ -46,14 +46,7 @@ public class MixinLightTexture
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
public void updateLightTexture(float partialTicks, CallbackInfo ci)
{
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (mc == null || mc.getWrappedClientLevel() == null)
{
return;
}
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels);
}
}
@@ -0,0 +1,27 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL 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 Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.forge.wrappers.modAccessor;
import com.seibel.distanthorizons.common.wrappers.modAccessor.AbstractImmersivePortalsAccessorCommon;
public class ImmersivePortalsAccessorForge extends AbstractImmersivePortalsAccessorCommon
{
}
@@ -30,14 +30,12 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.client.multiplayer.ClientLevel;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.level.LevelEvent;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
import net.minecraft.world.level.chunk.ChunkAccess;
@@ -52,13 +50,7 @@ import net.neoforged.neoforge.client.event.InputEvent;
import net.neoforged.bus.api.SubscribeEvent;
import org.lwjgl.opengl.GL32;
#if MC_VER < MC_1_20_6
import net.neoforged.neoforge.event.TickEvent;
#else
import net.neoforged.neoforge.client.event.ClientTickEvent;
import java.util.concurrent.AbstractExecutorService;
#endif
public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
@@ -73,43 +65,6 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
//==============//
// world events //
//==============//
@SubscribeEvent
public void clientLevelLoadEvent(LevelEvent.Load event)
{
LOGGER.info("level load");
LevelAccessor level = event.getLevel();
if (!(level instanceof ClientLevel))
{
return;
}
ClientLevel clientLevel = (ClientLevel) level;
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel, true);
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
}
@SubscribeEvent
public void clientLevelUnloadEvent(LevelEvent.Unload event)
{
LOGGER.info("level unload");
LevelAccessor level = event.getLevel();
if (!(level instanceof ClientLevel))
{
return;
}
ClientLevel clientLevel = (ClientLevel) level;
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
}
//==============//
// chunk events //
//==============//
@@ -163,11 +118,16 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
//LOGGER.trace("break or block attack at blockPos: " + event.getPos());
ChunkAccess chunk = level.getChunk(event.getPos());
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
this.onBlockChangeEvent(level, chunk);
});
}
}
}
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
{
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
}
@@ -260,8 +220,7 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
#else
// handled via the same mixin as fabric for consistency
#endif
try
{
// should generally only need to be set once per game session
@@ -30,16 +30,10 @@ import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IC2meAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.C2meAccessor;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.IrisAccessor;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.*;
import com.seibel.distanthorizons.neoforge.wrappers.NeoforgeMinecraftRenderWrapper;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.ModChecker;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.OptifineAccessor;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.MinecraftServer;
import net.neoforged.bus.api.EventPriority;
@@ -148,6 +142,7 @@ public class NeoforgeMain extends AbstractModInitializer
{
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
this.tryCreateModCompatAccessor("c2me", IC2meAccessor.class, C2meAccessor::new);
this.tryCreateModCompatAccessor("immersive_portals_core", IImmersivePortalsAccessor.class, ImmersivePortalsAccessorNeoForge::new);
#if MC_VER >= MC_1_20_6
// 1.20.6 is the lowest version Iris supports Neoforge
@@ -1,11 +1,8 @@
package com.seibel.distanthorizons.neoforge.mixins.client;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.ClientPacketListener;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -13,14 +10,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPacketListener.class)
public class MixinClientPacketListener
{
@Shadow
private ClientLevel level;
@Inject(method = "handleLogin", at = @At("RETURN"))
void onHandleLoginEnd(CallbackInfo ci)
{
ClientApi.INSTANCE.onClientOnlyConnected();
ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(this.level, true));
}
#if MC_VER < MC_1_19_4
@@ -0,0 +1,19 @@
package com.seibel.distanthorizons.neoforge.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.MixinImmersivePortalsRenderStatesCommon;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Pseudo
@Mixin(targets = "qouteall.imm_ptl.core.render.context_management.RenderStates")
public class MixinImmersivePortalsRenderStates
{
@Inject(method = "updatePreRenderInfo", at = @At("HEAD"))
private static void preRender(CallbackInfo ci)
{ MixinImmersivePortalsRenderStatesCommon.saveVolatileOriginals(); }
}
@@ -90,18 +90,6 @@ public class MixinLightTexture
public void render(LightmapRenderState renderState, CallbackInfo ci)
#endif
{
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (mc == null || mc.getWrappedClientLevel() == null)
{
return;
}
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
if (clientLevel == null)
{
return;
}
// lazy initialization to make sure we don't call this too early
if (this.renderWrapper == null)
{
@@ -110,21 +98,21 @@ public class MixinLightTexture
#if MC_VER < MC_1_21_3
renderWrapper.updateLightmap(this.lightPixels, clientLevel);
renderWrapper.updateLightmap(this.lightPixels);
#elif MC_VER < MC_1_21_5
renderWrapper.setLightmapId(this.target.getColorTextureId(), clientLevel);
renderWrapper.setLightmapId(this.target.getColorTextureId());
#elif MC_VER < MC_1_21_9
GlTexture glTexture = (GlTexture) this.texture;
renderWrapper.setLightmapId(glTexture.glId(), clientLevel);
renderWrapper.setLightmapId(glTexture.glId());
#elif MC_VER <= MC_1_21_10
GlTexture glTexture = (GlTexture) this.texture;
renderWrapper.setLightmapId(glTexture.glId(), clientLevel);
renderWrapper.setLightmapId(glTexture.glId());
#else
// both options are available since the renderer can be changed to either Blaze3D or OpenGL
int id = NeoforgeTextureUnwrapper.getGlTextureIdFromGpuTexture(this.texture);
renderWrapper.setLightmapId(id, clientLevel);
renderWrapper.setLightmapId(id);
renderWrapper.setLightmapGpuTexture(this.texture, clientLevel);
renderWrapper.setLightmapGpuTexture(this.texture);
#endif
}
@@ -0,0 +1,26 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL 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 Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.neoforge.wrappers.modAccessor;
import com.seibel.distanthorizons.common.wrappers.modAccessor.AbstractImmersivePortalsAccessorCommon;
public class ImmersivePortalsAccessorNeoForge extends AbstractImmersivePortalsAccessorCommon
{
}
-2
View File
@@ -25,7 +25,6 @@ fabric_api_version=0.42.0+1.16
sodium_version=mc1.16.5-0.2.0
iris_version=1.4.4+1.16.5
bclib_version=
immersive_portals_version=
canvas_version=
# iris - needs 1.7.4+ to support the DH API
@@ -44,7 +43,6 @@ fabric_api_version=0.42.0+1.16
enable_iris=1
# not available via github, use curse.maven if necessary
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# Forge loader
-2
View File
@@ -25,7 +25,6 @@ fabric_api_version=0.46.1+1.17
sodium_version=mc1.17.1-0.3.4
iris_version=1.17.x-v1.2.7
bclib_version=0.5.5
immersive_portals_version=
canvas_version=
# iris - needs 1.7.4+ to support the DH API
@@ -43,7 +42,6 @@ fabric_api_version=0.46.1+1.17
enable_sodium=1
enable_iris=0
enable_bclib=1
enable_immersive_portals=0
enable_canvas=0
# Forge loader
-2
View File
@@ -26,7 +26,6 @@ fabric_api_version=0.76.0+1.18.2
sodium_version=mc1.18.2-0.4.1
iris_version=1.6.10+1.18.2
bclib_version=1.4.6
immersive_portals_version=v1.4.11-1.18
canvas_version=mc118:1.0.2616
# iris - needs 1.7.4+ to support the DH API
@@ -44,7 +43,6 @@ fabric_api_version=0.76.0+1.18.2
enable_lithium=0
enable_iris=1
enable_bclib=1
enable_immersive_portals=0
enable_canvas=0
quilt_loader_version=0.19.1
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.76.1+1.19.2
sodium_version=mc1.19.2-0.4.4
iris_version=1.6.10+1.19.2
bclib_version=2.1.6
immersive_portals_version=
canvas_version=mc119-1.0.2480
# iris - needs 1.7.4+ to support the DH API
@@ -42,7 +41,6 @@ fabric_api_version=0.76.1+1.19.2
enable_lithium=0
enable_iris=1
enable_bclib=1
enable_immersive_portals=0
enable_canvas=0
# Forge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.87.1+1.19.4
sodium_version=mc1.19.4-0.4.10
iris_version=1.6.10+1.19.4
bclib_version=2.3.3
immersive_portals_version=
canvas_version=
# iris - needs 1.7.4+ to support the DH API
@@ -41,7 +40,6 @@ fabric_api_version=0.87.1+1.19.4
enable_lithium=0
enable_iris=1
enable_bclib=1
enable_immersive_portals=0
enable_canvas=0
# Forge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.92.6+1.20.1
sodium_version=mc1.20.1-0.5.3
iris_version=1.6.10+1.20.1
bclib_version=3.0.13
immersive_portals_version=
canvas_version=
# iris - needs 1.7.4+ to support the DH API
@@ -42,7 +41,6 @@ fabric_api_version=0.92.6+1.20.1
enable_lithium=0
enable_iris=1
enable_bclib=1
enable_immersive_portals=0
enable_canvas=0
# Forge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.90.4+1.20.2
sodium_version=mc1.20.2-0.5.3
iris_version=1.6.10+1.20.2
bclib_version=3.0.13
immersive_portals_version=
canvas_version=
# iris - needs 1.7.4+ to support the DH API
@@ -42,7 +41,6 @@ fabric_api_version=0.90.4+1.20.2
enable_lithium=0
enable_iris=1
enable_bclib=1
enable_immersive_portals=0
enable_canvas=0
# Forge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.91.2+1.20.4
sodium_version=mc1.20.3-0.5.4
iris_version=1.6.13+1.20.4
bclib_version=
immersive_portals_version=
canvas_version=
# iris - needs 1.7.4+ to support the DH API
@@ -43,7 +42,6 @@ fabric_api_version=0.91.2+1.20.4
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# Forge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.97.8+1.20.6
sodium_version=mc1.20.6-0.5.8
iris_version=1.7.0+1.20.6
bclib_version=
immersive_portals_version=
canvas_version=
# iris - needs 1.7.4+ to support the DH API
@@ -43,7 +42,6 @@ fabric_api_version=0.97.8+1.20.6
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.116.11+1.21.1
sodium_version=mc1.21.1-0.6.2-fabric
iris_version=1.8.1+1.21.1-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# iris - needs 1.7.4+ to support the DH API
@@ -43,7 +42,6 @@ fabric_api_version=0.116.11+1.21.1
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.138.4+1.21.10
sodium_version=mc1.21.10-0.7.2-fabric
iris_version=1.9.6+1.21.10-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# vertigo - prevents DH from seeing the full chunk, causing holes
@@ -41,7 +40,6 @@ fabric_api_version=0.138.4+1.21.10
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.139.4+1.21.11
sodium_version=mc1.21.11-0.8.0-fabric
iris_version=1.10.0+1.21.11-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# vertigo - prevents DH from seeing the full chunk, causing holes
@@ -41,7 +40,6 @@ fabric_api_version=0.139.4+1.21.11
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.110.0+1.21.3
sodium_version=mc1.21.3-0.6.0-fabric
iris_version=1.8.0+1.21.3-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# fabric-api 0.110.0 fixed a bug in MC 1.21.3 with the rendering API DH relied on
@@ -43,7 +42,6 @@ fabric_api_version=0.110.0+1.21.3
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.110.5+1.21.4
sodium_version=mc1.21.4-0.6.2-fabric
iris_version=1.8.2+1.21.4-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# vertigo - prevents DH from seeing the full chunk, causing holes
@@ -42,7 +41,6 @@ fabric_api_version=0.110.5+1.21.4
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.119.5+1.21.5
sodium_version=mc1.21.5-0.6.11-fabric
iris_version=1.8.10+1.21.5-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# Iris - some versions of 1.8.11 nightly builds may not work, but the ones after 2025-03-30 should
@@ -42,7 +41,6 @@ fabric_api_version=0.119.5+1.21.5
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.127.0+1.21.6
sodium_version=mc1.21.6-0.6.13-fabric
iris_version=1.9.0+1.21.6-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# vertigo - prevents DH from seeing the full chunk, causing holes
@@ -41,7 +40,6 @@ fabric_api_version=0.127.0+1.21.6
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.133.4+1.21.8
sodium_version=mc1.21.6-0.6.13-fabric
iris_version=1.9.1+1.21.7-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# vertigo - prevents DH from seeing the full chunk, causing holes
@@ -41,7 +40,6 @@ fabric_api_version=0.133.4+1.21.8
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.134.0+1.21.9
sodium_version=mc1.21.10-0.7.2-fabric
iris_version=1.9.3+1.21.9-fabric
bclib_version=
immersive_portals_version=
canvas_version=
# vertigo - prevents DH from seeing the full chunk, causing holes
@@ -41,7 +40,6 @@ fabric_api_version=0.134.0+1.21.9
enable_lithium=0
enable_iris=1
enable_bclib=0
enable_immersive_portals=0
enable_canvas=0
# NeoForge loader