Compare commits

...

34 Commits

Author SHA1 Message Date
James Seibel b6b108a287 Merge branch 'stable' of gitlab.com:jeseibel/distant-horizons into stable 2024-09-04 07:08:38 -05:00
James Seibel ab4ef429db Up version 2.2.1-dev -> 2.2.1 and API 3.0.0 -> 3.0.1 2024-09-04 06:58:28 -05:00
James Seibel 86473e022e Fix referencing unavailable GLFW methods for MC 1.18.2 and lower 2024-09-03 07:03:30 -05:00
James Seibel fd89f569d0 Fix MC 1.17.1 not compiling 2024-09-01 21:16:14 -05:00
James Seibel eefc765823 Fix LODs flashing while moving 2024-09-01 21:10:32 -05:00
James Seibel ebccb2516b Cull beacons based on X/Z distance instead of 3D distance 2024-09-01 17:28:13 -05:00
James Seibel 8c62a40da9 Disable instanced rendering on Mac when Sodium is present
Closes !793 (Generic Rendering crashes with Sodium on M1 Mac)
2024-09-01 17:02:49 -05:00
James Seibel d56af5c38f Fix some beacon rendering/updating issues 2024-09-01 16:36:41 -05:00
James Seibel 39b1ec61ba Fix glass panes not affecting beacon colors 2024-09-01 15:04:27 -05:00
James Seibel cb613cf7df add disableUnchangedChunkCheck config 2024-08-31 22:11:29 -05:00
James Seibel 28e33b4c36 Fix MC 1.16+ compiling 2024-08-31 22:11:14 -05:00
James Seibel 855e6b8180 Update pos getters and remove (hopefully) unneeded imports 2024-08-31 21:57:53 -05:00
James Seibel d62161f529 Fix cloud color not matching MC 2024-08-31 21:56:32 -05:00
James Seibel 71d48411f1 Add DhBlockPosMutable and make the original immutable 2024-08-30 07:36:04 -05:00
James Seibel 731842e09c Fix DH beacon detection logic breaking the lighting engine 2024-08-29 19:54:44 -05:00
James Seibel 61169f87c0 Fix LODs not updating underground 2024-08-29 07:33:21 -05:00
James Seibel 9fb3b196d2 Add a quick DH cloud UI config 2024-08-28 07:16:33 -05:00
James Seibel 867b875cf9 Fix Lithium breaking world gen for MC 1.20.1 and older 2024-08-27 19:19:09 -05:00
James Seibel 3875c8c4ce Up version number 2.2.0 -> 2.2.1-dev 2024-08-20 19:16:28 -05:00
James Seibel 2a37bec8ff Merge tag '2.1.2a' into stable 2024-07-28 08:07:35 -05:00
James Seibel f0f864d824 update architectury.loom 1.1 -> 1.3 and gradle 7.6 -> 8.1
gradle update was required by architectury
2024-01-07 21:58:09 -06:00
James Seibel 5abbff42d8 update manifold 2023.1.29 -> 23.1.31 2024-01-07 21:57:13 -06:00
James Seibel 53e2c4f806 update 1.20.4 forge 49.0.3 -> 49.0.14 2024-01-07 21:56:54 -06:00
Rózsa Péter cb4c32e0a9 Fix clone URL
(cherry picked from commit 39b77c783b)
2023-12-25 18:37:02 +10:30
coolGi c620086ed1 Revert "Fixed 1.20.4 forge remap"
This reverts commit 0d565895e2.
2023-12-24 19:03:38 +10:30
coolGi 513cecf318 Revert "Hopefully fixed forge stable on 1.20.4"
This reverts commit 749921b436.
2023-12-24 19:03:31 +10:30
coolGi 749921b436 Hopefully fixed forge stable on 1.20.4 2023-12-23 15:39:20 +10:30
coolGi 0d565895e2 Fixed 1.20.4 forge remap
(cherry picked from commit 28d4cc86a9)
2023-12-23 15:35:12 +10:30
coolGi 2c6849a0fd Updated to new git url
(cherry picked from commit 0d7b0f9fe4)
2023-12-23 15:34:16 +10:30
James Seibel 4d53ec5b64 Fix forge 1.20.4 crashing due to incorrect version number order
(cherry picked from commit d597634ac6)
2023-12-23 15:33:59 +10:30
coolGi 4467af4798 Updated ci to include 1.20.4 2023-12-09 04:17:50 +00:00
coolGi d3f953686a Fixed up screens looking incorrect on 1.20.4 mc versions
(cherry picked from commit 04ddd83519)
2023-12-09 14:41:35 +10:30
coolGi 67901d82c5 Updated to 1.20.3/4
(cherry picked from commit 5b81ca2716)
2023-12-09 14:13:50 +10:30
James Seibel 013fbf638a Merge branch 'main' into 'stable'
merge 2.0.1a

See merge request jeseibel/distant-horizons!45
2023-12-04 01:11:27 +00:00
13 changed files with 87 additions and 82 deletions
@@ -20,11 +20,9 @@
package com.seibel.distanthorizons.common.wrappers;
import java.nio.FloatBuffer;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.util.math.Mat4f;
@@ -137,41 +135,10 @@ public class McObjectConverter
}
}
public static BlockPos Convert(DhBlockPos wrappedPos)
{
return new BlockPos(wrappedPos.x, wrappedPos.y, wrappedPos.z);
}
public static ChunkPos Convert(DhChunkPos wrappedPos)
{
return new ChunkPos(wrappedPos.x, wrappedPos.z);
}
public static BlockPos Convert(DhBlockPos wrappedPos) { return new BlockPos(wrappedPos.getX(), wrappedPos.getY(), wrappedPos.getZ()); }
public static ChunkPos Convert(DhChunkPos wrappedPos) { return new ChunkPos(wrappedPos.getX(), wrappedPos.getZ()); }
public static Direction Convert(EDhDirection lodDirection)
{
return directions[lodDirection.ordinal()];
}
public static EDhDirection Convert(Direction direction)
{
return lodDirections[direction.ordinal()];
}
public static void DebugCheckAllPackers()
{
BiConsumer<Integer, Integer> func = (x, z) -> DhChunkPos._DebugCheckPacker(x, z, ChunkPos.asLong(x, z));
func.accept(0, 0);
func.accept(12345, 134);
func.accept(-12345, -134);
func.accept(-30000000 / 16, 30000000 / 16);
func.accept(30000000 / 16, -30000000 / 16);
func.accept(30000000 / 16, 30000000 / 16);
func.accept(-30000000 / 16, -30000000 / 16);
Consumer<BlockPos> func2 = (p) -> DhBlockPos._DebugCheckPacker(p.getX(), p.getY(), p.getZ(), p.asLong());
func2.accept(new BlockPos(0, 0, 0));
func2.accept(new BlockPos(12345, 134, 123));
func2.accept(new BlockPos(-12345, -134, -80));
func2.accept(new BlockPos(-30000000, 2047, 30000000));
func2.accept(new BlockPos(30000000, -2048, -30000000));
func2.accept(new BlockPos(30000000, 2047, 30000000));
func2.accept(new BlockPos(-30000000, -2048, -30000000));
}
public static Direction Convert(EDhDirection lodDirection) { return directions[lodDirection.ordinal()]; }
public static EDhDirection Convert(Direction direction) { return lodDirections[direction.ordinal()]; }
}
@@ -30,6 +30,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrappe
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.BeaconBeamBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.SoundType;
@@ -102,8 +103,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
private byte blockMaterialId = 0;
private final boolean isBeaconBlock;
private final boolean isBeaconBaseBlock;
private final boolean isGlassBlock;
private final boolean isBeaconBaseBlock;
/** null if this block can't tint beacons */
private final Color beaconTintColor;
private final Color mapColor;
@@ -139,6 +141,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
this.hashCode = Objects.hash(this.serialString);
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
// beacon blocks
String lowercaseSerial = this.serialString.toLowerCase();
boolean isBeaconBaseBlock = false;
for (int i = 0; i < LodUtil.BEACON_BASE_BLOCK_NAME_LIST.size(); i++)
@@ -152,7 +155,28 @@ public class BlockStateWrapper implements IBlockStateWrapper
}
this.isBeaconBaseBlock = isBeaconBaseBlock;
this.isBeaconBlock = lowercaseSerial.contains("minecraft:beacon");
this.isGlassBlock = lowercaseSerial.contains("glass");
// beacon tint color
Color beaconTintColor = null;
if (this.blockState != null
// beacon blocks also show up here, but since they block the beacon beam we don't want their color
&& !this.isBeaconBlock)
{
Block block = this.blockState.getBlock();
if (block instanceof BeaconBeamBlock)
{
int colorInt;
#if MC_VER <= MC_1_19_4
colorInt = ((BeaconBeamBlock) block).getColor().getMaterialColor().col;
#else
colorInt = ((BeaconBeamBlock) block).getColor().getMapColor().col;
#endif
beaconTintColor = ColorUtil.toColorObjRGB(colorInt);
}
}
this.beaconTintColor = beaconTintColor;
int mcColor = 0;
if (this.blockState != null)
@@ -399,10 +423,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
@Override
public boolean isBeaconBaseBlock() { return this.isBeaconBaseBlock; }
@Override
public boolean isGlassBlock() { return this.isGlassBlock; }
public boolean isBeaconTintBlock() { return this.beaconTintColor != null; }
@Override
public Color getMapColor() { return this.mapColor; }
@Override
public Color getBeaconTintColor() { return this.beaconTintColor; }
@Override
public byte getMaterialId() { return this.blockMaterialId; }
@@ -19,13 +19,9 @@
package com.seibel.distanthorizons.common.wrappers.block;
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
import com.seibel.distanthorizons.common.wrappers.block.TextureAtlasSpriteWrapper;
import com.seibel.distanthorizons.common.wrappers.block.TintWithoutLevelOverrider;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.block.*;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft;
@@ -23,7 +23,7 @@ import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.DhLitWorldGenRegion;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
@@ -463,7 +463,7 @@ public class ChunkWrapper implements IChunkWrapper
* before the list has finished populating.
*/
@Override
public synchronized ArrayList<DhBlockPos> getBlockLightPosList()
public synchronized ArrayList<DhBlockPos> getWorldBlockLightPosList()
{
// only populate the list once
if (this.blockLightPosList == null)
@@ -479,7 +479,13 @@ public class ChunkWrapper implements IChunkWrapper
#else
this.chunk.findBlockLightSources((blockPos, blockState) ->
{
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
DhBlockPos pos = new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ());
// this can be uncommented if MC decides to return relative block positions in the future instead of world positions
//pos.mutateToChunkRelativePos(pos);
//pos.mutateOffset(this.chunkPos.getMinBlockX(), 0, this.chunkPos.getMinBlockZ(), pos);
this.blockLightPosList.add(pos);
});
#endif
}
@@ -39,14 +39,13 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftCli
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import net.minecraft.CrashReport;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
#if MC_VER < MC_1_19_2
@@ -21,29 +21,26 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
import java.awt.Color;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.WrapperFactory;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
#if MC_VER >= MC_1_17_1
import net.minecraft.client.renderer.FogRenderer;
import com.mojang.blaze3d.systems.RenderSystem;
#endif
#if MC_VER < MC_1_19_4
import org.joml.Matrix4f;
import org.joml.Vector3f;
#else
import org.joml.Matrix4f;
import org.joml.Vector3f;
#endif
#if MC_VER >= MC_1_20_2
import net.minecraft.client.renderer.chunk.SectionRenderDispatcher;
@@ -53,20 +50,14 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOpt
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.effect.MobEffects;
#if MC_VER < MC_1_17_1
import net.minecraft.tags.FluidTags;
@@ -76,7 +67,6 @@ import org.lwjgl.opengl.GL15;
#else
import net.minecraft.world.level.material.FogType;
#endif
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.apache.logging.log4j.Logger;
@@ -7,13 +7,11 @@ 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.chunk.ChunkWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.level.*;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
@@ -26,10 +24,12 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.phys.Vec3;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
@@ -207,12 +207,12 @@ public class ClientLevelWrapper implements IClientLevelWrapper
@Override
public IChunkWrapper tryGetChunk(DhChunkPos pos)
{
if (!this.level.hasChunk(pos.x, pos.z))
if (!this.level.hasChunk(pos.getX(), pos.getZ()))
{
return null;
}
ChunkAccess chunk = this.level.getChunk(pos.x, pos.z, ChunkStatus.EMPTY, false);
ChunkAccess chunk = this.level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.EMPTY, false);
if (chunk == null)
{
return null;
@@ -267,6 +267,13 @@ public class ClientLevelWrapper implements IClientLevelWrapper
return this.parentDhLevel.getGenericRenderer();
}
@Override
public Color getCloudColor(float tickDelta)
{
Vec3 colorVec3 = this.level.getCloudColor(tickDelta);
return new Color((float)colorVec3.x, (float)colorVec3.y, (float)colorVec3.z);
}
//================//
@@ -30,7 +30,7 @@ import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
@@ -48,7 +48,6 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
#endif
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
/**
* @version 2022-9-16
@@ -132,8 +131,8 @@ public class ServerLevelWrapper implements IServerLevelWrapper
@Override
public IChunkWrapper tryGetChunk(DhChunkPos pos)
{
if (!level.hasChunk(pos.x, pos.z)) return null;
ChunkAccess chunk = level.getChunk(pos.x, pos.z, ChunkStatus.FULL, false);
if (!level.hasChunk(pos.getX(), pos.getZ())) return null;
ChunkAccess chunk = level.getChunk(pos.getX(), pos.getZ(), ChunkStatus.FULL, false);
if (chunk == null) return null;
return new ChunkWrapper(chunk, level, this);
}
@@ -398,8 +398,8 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
int borderSize = MAX_WORLD_GEN_CHUNK_BORDER_NEEDED;
// genEvent.size - 1 converts the even width size to an odd number for MC compatability
int refSize = (genEvent.size - 1) + (borderSize * 2);
int refPosX = genEvent.minPos.x - borderSize;
int refPosZ = genEvent.minPos.z - borderSize;
int refPosX = genEvent.minPos.getX() - borderSize;
int refPosZ = genEvent.minPos.getZ() - borderSize;
LightGetterAdaptor lightGetterAdaptor = new LightGetterAdaptor(this.params.level);
DummyLightEngine dummyLightEngine = new DummyLightEngine(lightGetterAdaptor);
@@ -20,7 +20,6 @@
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
import java.lang.invoke.MethodHandles;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
@@ -235,6 +234,22 @@ public class DhLitWorldGenRegion extends WorldGenRegion
#endif
}
/**
* This needs to be manually overridden to make sure Lithium 0.11.2 and lower
* don't try to get null chunks. <br><br>
*
* Problematic Lithium code was removed in 0.13.0 (MC 1.21.1) and higher: <br>
* https://github.com/CaffeineMC/lithium-fabric/commit/b7cfd53a1ed0197e1d13dea2799b898eb52ecab3
*/
@NotNull
@Override
public BlockState getBlockState(BlockPos blockPos)
{
int chunkX = SectionPos.blockToSectionCoord(blockPos.getX());
int chunkZ = SectionPos.blockToSectionCoord(blockPos.getZ());
return this.getChunk(chunkX, chunkZ).getBlockState(blockPos);
}
/** Skip BlockEntity stuff. They aren't needed for our use case. */
@Override
public boolean addFreshEntity(@NotNull Entity entity) { return true; }
@@ -80,7 +80,7 @@ public final class StepFeatures
worldGenRegion.setOverrideCenter(chunk.getPos());
environment.params.generator.applyBiomeDecoration(worldGenRegion, tParams.structFeat);
#else
if (worldGenRegion.hasChunk(chunkWrapper.getChunkPos().x, chunkWrapper.getChunkPos().z))
if (worldGenRegion.hasChunk(chunkWrapper.getChunkPos().getX(), chunkWrapper.getChunkPos().getZ()))
{
this.environment.params.generator.applyBiomeDecoration(worldGenRegion, chunk, tParams.structFeat.forWorldGenRegion(worldGenRegion));
}
+1 -1
View File
@@ -5,7 +5,7 @@ org.gradle.caching=true
# Mod Info
mod_name=DistantHorizons
mod_version=2.2.0-a
mod_version=2.2.1-a
api_version=3.0.0
maven_group=com.seibel.distanthorizons
mod_readable_name=Distant Horizons