Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 095fff96ff | |||
| a23211d061 | |||
| b57ea41686 | |||
| 62fb5ffb73 | |||
| 99c713967b | |||
| 9f3de07bd8 | |||
| cd74117de3 | |||
| e7d7033548 | |||
| 34db7c9dac | |||
| 272841aae9 | |||
| 389b09a5cd | |||
| 84bd876c71 | |||
| 7e45051ffd | |||
| 5570f3a313 | |||
| f4e71f7012 | |||
| 601d4e6e3a | |||
| a12092c1a1 | |||
| 94ad118c5d | |||
| 48e2978438 | |||
| 96b4c1a9e8 | |||
| cc4a69c10c | |||
| 7293677ddb | |||
| 0f2ff20375 | |||
| 7706240acb | |||
| 4cf48fd997 | |||
| 2708c1ee11 | |||
| ebb0f6ebad | |||
| 2c263a2549 | |||
| 955524c632 | |||
| 564e0d3263 | |||
| c533b2e8ea | |||
| 6073d8122a |
+1
-1
@@ -30,7 +30,7 @@ build:
|
|||||||
stage: build
|
stage: build
|
||||||
parallel:
|
parallel:
|
||||||
matrix:
|
matrix:
|
||||||
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2", "1.20.4", "1.20.6"]
|
- MC_VER: ["1.16.5", "1.17.1", "1.18.2", "1.19.2", "1.19.4", "1.20.1", "1.20.2", "1.20.4", "1.20.6", "1.21"]
|
||||||
script:
|
script:
|
||||||
# this both runs the unit tests and assembles the code
|
# this both runs the unit tests and assembles the code
|
||||||
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||||
|
|||||||
+19
-14
@@ -54,7 +54,7 @@ def writeBuildGradlePredefine(List<String> mcVers, int mcIndex)
|
|||||||
// Transfers the values set in settings.gradle to the rest of the project
|
// Transfers the values set in settings.gradle to the rest of the project
|
||||||
project.gradle.ext.getProperties().each { prop ->
|
project.gradle.ext.getProperties().each { prop ->
|
||||||
rootProject.ext.set(prop.key, prop.value)
|
rootProject.ext.set(prop.key, prop.value)
|
||||||
// println "Added prop [key:" + prop.key + ", value:" + prop.value + "]"
|
//println "Added prop [key:" + prop.key + ", value:" + prop.value + "]"
|
||||||
}
|
}
|
||||||
// Sets up manifold stuff
|
// Sets up manifold stuff
|
||||||
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
|
||||||
@@ -106,11 +106,12 @@ subprojects { p ->
|
|||||||
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
apply plugin: "systems.manifold.manifold-gradle-plugin"
|
||||||
|
|
||||||
// Apply forge's loom
|
// Apply forge's loom
|
||||||
if (
|
if ((findProject(":forge") && p == project(":forge")) ||
|
||||||
(findProject(":forge") && p == project(":forge")) ||
|
(findProject(":neoforge") && p == project(":neoforge"))
|
||||||
(findProject(":neoforge") && p == project(":neoforge"))
|
)
|
||||||
)
|
{
|
||||||
apply plugin: "dev.architectury.loom"
|
apply plugin: "dev.architectury.loom"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set the manifold version (may not be required tough)
|
// Set the manifold version (may not be required tough)
|
||||||
@@ -430,9 +431,11 @@ subprojects { p ->
|
|||||||
jar {
|
jar {
|
||||||
from "LICENSE.txt"
|
from "LICENSE.txt"
|
||||||
manifest {
|
manifest {
|
||||||
attributes 'Implementation-Title': rootProject.mod_name,
|
attributes(
|
||||||
'Implementation-Version': rootProject.mod_version,
|
'Implementation-Title': rootProject.mod_name,
|
||||||
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain' // When changing the main of the jar change this line
|
'Implementation-Version': rootProject.mod_version,
|
||||||
|
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain' // When changing the main of the jar change this line
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,14 +524,16 @@ allprojects { p ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required for ModMenu
|
// VanillaGradle and Mixins in common
|
||||||
maven { url "https://maven.terraformersmc.com/" }
|
|
||||||
|
|
||||||
// Required for Mixins & VanillaGradle
|
|
||||||
maven { url "https://repo.spongepowered.org/maven/" }
|
maven { url "https://repo.spongepowered.org/maven/" }
|
||||||
|
|
||||||
// Required for Canvas (mod)
|
// Canvas mod
|
||||||
maven { url "https://maven.vram.io/" }
|
maven { url "https://maven.vram.io/" }
|
||||||
|
// ModMenu mod
|
||||||
|
maven { url "https://maven.terraformersmc.com/" }
|
||||||
|
|
||||||
|
// neoforge
|
||||||
|
maven { url "https://maven.neoforged.net/releases/" }
|
||||||
|
|
||||||
// These 3 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
|
// These 3 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
|
||||||
flatDir {
|
flatDir {
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
|
|
||||||
|
// temporary fix for broken spongepowered version
|
||||||
|
buildscript {
|
||||||
|
configurations.configureEach {
|
||||||
|
resolutionStrategy {
|
||||||
|
force 'org.spongepowered:vanillagradle:0.2.1-20240507.024226-82'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "org.spongepowered.gradle.vanilla" version "0.2.1-SNAPSHOT"
|
id "org.spongepowered.gradle.vanilla" version "0.2.1-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_6
|
#if MC_VER <= MC_1_21
|
||||||
else if (objectArray.length == 2)
|
else if (objectArray.length == 2)
|
||||||
{
|
{
|
||||||
// correct number of parameters from the API
|
// correct number of parameters from the API
|
||||||
@@ -195,7 +195,7 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
{
|
{
|
||||||
String[] expectedClassNames;
|
String[] expectedClassNames;
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_6
|
#if MC_VER <= MC_1_21
|
||||||
expectedClassNames = new String[]
|
expectedClassNames = new String[]
|
||||||
{
|
{
|
||||||
ChunkAccess.class.getName(),
|
ChunkAccess.class.getName(),
|
||||||
@@ -243,7 +243,7 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
|
|
||||||
Biome biome = (Biome) objectArray[0];
|
Biome biome = (Biome) objectArray[0];
|
||||||
return BiomeWrapper.getBiomeWrapper(biome, coreLevelWrapper);
|
return BiomeWrapper.getBiomeWrapper(biome, coreLevelWrapper);
|
||||||
#elif MC_VER <= MC_1_20_6
|
#elif MC_VER <= MC_1_21
|
||||||
if (!(objectArray[0] instanceof Holder) || !(((Holder<?>) objectArray[0]).value() instanceof Biome))
|
if (!(objectArray[0] instanceof Holder) || !(((Holder<?>) objectArray[0]).value() instanceof Biome))
|
||||||
{
|
{
|
||||||
throw new ClassCastException(createBiomeWrapperErrorMessage(objectArray));
|
throw new ClassCastException(createBiomeWrapperErrorMessage(objectArray));
|
||||||
@@ -266,7 +266,7 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
expectedClassNames = new String[] { Biome.class.getName() };
|
expectedClassNames = new String[] { Biome.class.getName() };
|
||||||
#elif MC_VER <= MC_1_20_6
|
#elif MC_VER <= MC_1_21
|
||||||
expectedClassNames = new String[] { Holder.class.getName()+"<"+Biome.class.getName()+">" };
|
expectedClassNames = new String[] { Holder.class.getName()+"<"+Biome.class.getName()+">" };
|
||||||
#else
|
#else
|
||||||
// See preprocessor comment in createChunkWrapper() for full documentation
|
// See preprocessor comment in createChunkWrapper() for full documentation
|
||||||
@@ -287,7 +287,7 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER <= MC_1_20_6
|
#if MC_VER <= MC_1_21
|
||||||
if (objectArray.length != 1)
|
if (objectArray.length != 1)
|
||||||
{
|
{
|
||||||
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
|
||||||
@@ -314,7 +314,7 @@ public class WrapperFactory implements IWrapperFactory
|
|||||||
|
|
||||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
expectedClassNames = new String[] { Biome.class.getName() };
|
expectedClassNames = new String[] { Biome.class.getName() };
|
||||||
#elif MC_VER <= MC_1_20_6
|
#elif MC_VER <= MC_1_21
|
||||||
expectedClassNames = new String[] { Holder.class.getName()+"<"+Biome.class.getName()+">" };
|
expectedClassNames = new String[] { Holder.class.getName()+"<"+Biome.class.getName()+">" };
|
||||||
#else
|
#else
|
||||||
// See preprocessor comment in createChunkWrapper() for full documentation
|
// See preprocessor comment in createChunkWrapper() for full documentation
|
||||||
|
|||||||
+4
@@ -293,7 +293,11 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
ResourceLocation resourceLocation;
|
ResourceLocation resourceLocation;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
||||||
|
#else
|
||||||
|
resourceLocation = ResourceLocation.fromNamespaceAndPath(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex + 1));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
+4
@@ -380,7 +380,11 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
ResourceLocation resourceLocation;
|
ResourceLocation resourceLocation;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
resourceLocation = new ResourceLocation(resourceStateString.substring(0, separatorIndex), resourceStateString.substring(separatorIndex + 1));
|
resourceLocation = new ResourceLocation(resourceStateString.substring(0, separatorIndex), resourceStateString.substring(separatorIndex + 1));
|
||||||
|
#else
|
||||||
|
resourceLocation = ResourceLocation.fromNamespaceAndPath(resourceStateString.substring(0, separatorIndex), resourceStateString.substring(separatorIndex + 1));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
-239
@@ -1,239 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Distant Horizons mod
|
|
||||||
* licensed under the GNU LGPL v3 License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020-2023 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.chunk;
|
|
||||||
|
|
||||||
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compact, efficient storage for light levels.
|
|
||||||
* all blocks only take up 4 bits in total,
|
|
||||||
* and if a 16x16x16 area is detected to have the same light level in all positions,
|
|
||||||
* then we store a single byte for that light level, instead of 2 kilobytes.
|
|
||||||
*
|
|
||||||
* @author Builderb0y
|
|
||||||
*/
|
|
||||||
public class ChunkLightStorage
|
|
||||||
{
|
|
||||||
/** the minimum Y level in the chunk which this storage is storing light levels for (inclusive). */
|
|
||||||
public int minY;
|
|
||||||
/** the maximum Y level in the chunk which this storage is storing light levels for (exclusive). */
|
|
||||||
public int maxY;
|
|
||||||
|
|
||||||
/** the data stored in this storage, split up into 16x16x16 areas. */
|
|
||||||
public LightSection[] lightSections;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the get method is called on a Y position above what's stored
|
|
||||||
* this value will be returned. <br><br>
|
|
||||||
*
|
|
||||||
* This needs to be manually defined since sky and block lights behave differently
|
|
||||||
* for values both above and below what's defined.
|
|
||||||
*/
|
|
||||||
public int aboveMaxYValue;
|
|
||||||
/** @see ChunkLightStorage#aboveMaxYValue */
|
|
||||||
public int belowMinYValue;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
|
||||||
// constructor //
|
|
||||||
//=============//
|
|
||||||
|
|
||||||
public ChunkLightStorage(int minY, int maxY, int aboveMaxYValue, int belowMinYValue)
|
|
||||||
{
|
|
||||||
this.minY = minY;
|
|
||||||
this.maxY = maxY;
|
|
||||||
|
|
||||||
this.aboveMaxYValue = aboveMaxYValue;
|
|
||||||
this.belowMinYValue = belowMinYValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=====================//
|
|
||||||
// getters and setters //
|
|
||||||
//=====================//
|
|
||||||
|
|
||||||
public int get(int x, int y, int z)
|
|
||||||
{
|
|
||||||
if (y < this.minY)
|
|
||||||
{
|
|
||||||
return this.belowMinYValue;
|
|
||||||
}
|
|
||||||
else if (y >= this.maxY)
|
|
||||||
{
|
|
||||||
return this.aboveMaxYValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (this.lightSections != null)
|
|
||||||
{
|
|
||||||
LightSection lightSection = this.lightSections[BitShiftUtil.divideByPowerOfTwo(y - this.minY, 4)];
|
|
||||||
if (lightSection != null)
|
|
||||||
{
|
|
||||||
return lightSection.get(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(int x, int y, int z, int lightLevel)
|
|
||||||
{
|
|
||||||
if (y < this.minY || y >= this.maxY)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//populate array if it doesn't exist.
|
|
||||||
if (this.lightSections == null)
|
|
||||||
{
|
|
||||||
this.lightSections = new LightSection[BitShiftUtil.divideByPowerOfTwo(this.maxY - this.minY, 4)];
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = (y - this.minY) >> 4;
|
|
||||||
LightSection lightSection = this.lightSections[index];
|
|
||||||
|
|
||||||
//populate lightSection in array if it doesn't exist.
|
|
||||||
if (lightSection == null)
|
|
||||||
{
|
|
||||||
lightSection = new LightSection(0);
|
|
||||||
this.lightSections[index] = lightSection;
|
|
||||||
}
|
|
||||||
lightSection.set(x, y, z, lightLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// helper classes //
|
|
||||||
//================//
|
|
||||||
|
|
||||||
public static class LightSection
|
|
||||||
{
|
|
||||||
public byte constantValue;
|
|
||||||
public long[] data;
|
|
||||||
public short[] counts;
|
|
||||||
|
|
||||||
public LightSection(int initialValue)
|
|
||||||
{
|
|
||||||
this.constantValue = (byte) (initialValue);
|
|
||||||
this.counts = new short[16];
|
|
||||||
this.counts[initialValue] = 16 * 16 * 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int get(int x, int y, int z)
|
|
||||||
{
|
|
||||||
if (this.constantValue >= 0)
|
|
||||||
{
|
|
||||||
return this.constantValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
x &= 15;
|
|
||||||
y &= 15;
|
|
||||||
z &= 15;
|
|
||||||
long bits = this.data[(z << 4) | x];
|
|
||||||
return ((int) (bits >>> (y << 2))) & 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(int x, int y, int z, int lightLevel)
|
|
||||||
{
|
|
||||||
int oldLightLevel = -1;
|
|
||||||
if (this.constantValue >= 0)
|
|
||||||
{
|
|
||||||
oldLightLevel = this.constantValue;
|
|
||||||
|
|
||||||
//if the light level didn't change, then there's nothing to do.
|
|
||||||
if (oldLightLevel == lightLevel) return;
|
|
||||||
|
|
||||||
//if we are a constant value and need to change something,
|
|
||||||
//then that means we need to convert to a non-constant value.
|
|
||||||
this.data = DataRecycler.get();
|
|
||||||
|
|
||||||
//repeat oldLightLevel 16 times as a bit pattern.
|
|
||||||
long payload = oldLightLevel;
|
|
||||||
payload |= payload << 4;
|
|
||||||
payload |= payload << 8;
|
|
||||||
payload |= payload << 16;
|
|
||||||
payload |= payload << 32;
|
|
||||||
|
|
||||||
//fill our data with our constant value.
|
|
||||||
Arrays.fill(this.data, payload);
|
|
||||||
|
|
||||||
//we are no longer a constant value.
|
|
||||||
this.constantValue = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
x &= 15;
|
|
||||||
y &= 15;
|
|
||||||
z &= 15;
|
|
||||||
int index = (z << 4) | x;
|
|
||||||
long bits = this.data[index];
|
|
||||||
//if we weren't a constant value before, now's the time to initialize oldLightLevel.
|
|
||||||
if (oldLightLevel < 0)
|
|
||||||
{
|
|
||||||
oldLightLevel = ((int) (bits >>> (y << 2))) & 15;
|
|
||||||
}
|
|
||||||
//clear the 4 bits that correspond to the light level at x, y, z...
|
|
||||||
bits &= ~(15L << (y << 2));
|
|
||||||
//...and then re-populate those bits with the new light level.
|
|
||||||
bits |= ((long) (lightLevel)) << (y << 2);
|
|
||||||
//store the updated bits in our data.
|
|
||||||
this.data[index] = bits;
|
|
||||||
|
|
||||||
//we have one less of the old light level...
|
|
||||||
this.counts[oldLightLevel]--;
|
|
||||||
//...and one more of the new level.
|
|
||||||
//if the number associated with the new level is now 4096 (AKA 16 ^ 3),
|
|
||||||
//then this implies every position in this section has the same light level,
|
|
||||||
//and therefore we can convert back to a constant value.
|
|
||||||
if (++this.counts[lightLevel] == 4096)
|
|
||||||
{
|
|
||||||
this.constantValue = (byte) (lightLevel);
|
|
||||||
DataRecycler.reclaim(this.data);
|
|
||||||
this.data = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static class DataRecycler
|
|
||||||
{
|
|
||||||
private static final ArrayList<long[]> recycled = new ArrayList<>(256);
|
|
||||||
|
|
||||||
static synchronized long[] get()
|
|
||||||
{
|
|
||||||
if (recycled.isEmpty())
|
|
||||||
{
|
|
||||||
return new long[256];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return recycled.remove(recycled.size() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static synchronized void reclaim(long[] data) { if (recycled.size() < 256) recycled.add(data); }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+84
-118
@@ -25,13 +25,12 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.Dh
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
|
||||||
import net.minecraft.client.multiplayer.ClientChunkCache;
|
import net.minecraft.client.multiplayer.ClientChunkCache;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@@ -83,9 +82,6 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
{
|
{
|
||||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||||
|
|
||||||
/** useful for debugging, but can slow down chunk operations quite a bit due to being called every time. */
|
|
||||||
private static final boolean RUN_RELATIVE_POS_INDEX_VALIDATION = ModInfo.IS_DEV_BUILD;
|
|
||||||
|
|
||||||
/** can be used for interactions with the underlying chunk where creating new BlockPos objects could cause issues for the garbage collector. */
|
/** can be used for interactions with the underlying chunk where creating new BlockPos objects could cause issues for the garbage collector. */
|
||||||
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
private static final ThreadLocal<BlockPos.MutableBlockPos> MUTABLE_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos());
|
||||||
|
|
||||||
@@ -109,6 +105,8 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
private int minNonEmptyHeight = Integer.MIN_VALUE;
|
private int minNonEmptyHeight = Integer.MIN_VALUE;
|
||||||
private int maxNonEmptyHeight = Integer.MAX_VALUE;
|
private int maxNonEmptyHeight = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
private int blockBiomeHashCode = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Due to vanilla `isClientLightReady()` not being designed for use by a non-render thread, it may return 'true'
|
* Due to vanilla `isClientLightReady()` not being designed for use by a non-render thread, it may return 'true'
|
||||||
* before the light engine has ticked, (right after all light changes is marked by the engine to be processed).
|
* before the light engine has ticked, (right after all light changes is marked by the engine to be processed).
|
||||||
@@ -148,30 +146,34 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
|
|
||||||
//=========//
|
//=========//
|
||||||
// methods //
|
// getters //
|
||||||
//=========//
|
//=========//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight()
|
public int getHeight() { return getHeight(this.chunk); }
|
||||||
|
public static int getHeight(ChunkAccess chunk)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 255;
|
return 255;
|
||||||
#else
|
#else
|
||||||
return this.chunk.getHeight();
|
return chunk.getHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight()
|
public int getMinBuildHeight() { return getMinBuildHeight(this.chunk); }
|
||||||
|
public static int getMinBuildHeight(ChunkAccess chunk)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return this.chunk.getMinBuildHeight();
|
return chunk.getMinBuildHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxBuildHeight() { return this.chunk.getMaxBuildHeight(); }
|
public int getMaxBuildHeight() { return getMaxBuildHeight(this.chunk); }
|
||||||
|
public static int getMaxBuildHeight(ChunkAccess chunk) { return chunk.getMaxBuildHeight(); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinNonEmptyHeight()
|
public int getMinNonEmptyHeight()
|
||||||
@@ -263,7 +265,6 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
public int getLightBlockingHeightMapValue(int xRel, int zRel) { return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.MOTION_BLOCKING).getFirstAvailable(xRel, zRel); }
|
public int getLightBlockingHeightMapValue(int xRel, int zRel) { return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.MOTION_BLOCKING).getFirstAvailable(xRel, zRel); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBiomeWrapper getBiome(int relX, int relY, int relZ)
|
public IBiomeWrapper getBiome(int relX, int relY, int relZ)
|
||||||
{
|
{
|
||||||
@@ -287,11 +288,35 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockStateWrapper getBlockState(int relX, int relY, int relZ)
|
||||||
|
{
|
||||||
|
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
|
||||||
|
|
||||||
|
BlockPos.MutableBlockPos blockPos = MUTABLE_BLOCK_POS_REF.get();
|
||||||
|
|
||||||
|
blockPos.setX(relX);
|
||||||
|
blockPos.setY(relY);
|
||||||
|
blockPos.setZ(relZ);
|
||||||
|
|
||||||
|
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(blockPos), this.wrappedLevel);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DhChunkPos getChunkPos() { return this.chunkPos; }
|
public DhChunkPos getChunkPos() { return this.chunkPos; }
|
||||||
|
|
||||||
public ChunkAccess getChunk() { return this.chunk; }
|
public ChunkAccess getChunk() { return this.chunk; }
|
||||||
|
|
||||||
|
public ChunkStatus getStatus() { return getStatus(this.getChunk()); }
|
||||||
|
public static ChunkStatus getStatus(ChunkAccess chunk)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
return chunk.getStatus();
|
||||||
|
#else
|
||||||
|
return chunk.getPersistedStatus();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxBlockX() { return this.chunk.getPos().getMaxBlockX(); }
|
public int getMaxBlockX() { return this.chunk.getPos().getMaxBlockX(); }
|
||||||
@Override
|
@Override
|
||||||
@@ -301,8 +326,11 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
@Override
|
@Override
|
||||||
public int getMinBlockZ() { return this.chunk.getPos().getMinBlockZ(); }
|
public int getMinBlockZ() { return this.chunk.getPos().getMinBlockZ(); }
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLongChunkPos() { return this.chunk.getPos().toLong(); }
|
|
||||||
|
//==========//
|
||||||
|
// lighting //
|
||||||
|
//==========//
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIsDhLightCorrect(boolean isDhLightCorrect) { this.isDhLightCorrect = isDhLightCorrect; }
|
public void setIsDhLightCorrect(boolean isDhLightCorrect) { this.isDhLightCorrect = isDhLightCorrect; }
|
||||||
@@ -310,8 +338,6 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
@Override
|
@Override
|
||||||
public void setUseDhLighting(boolean useDhLighting) { this.useDhLighting = useDhLighting; }
|
public void setUseDhLighting(boolean useDhLighting) { this.useDhLighting = useDhLighting; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLightCorrect()
|
public boolean isLightCorrect()
|
||||||
{
|
{
|
||||||
@@ -364,13 +390,11 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
{
|
{
|
||||||
if (this.blockLightStorage == null)
|
if (this.blockLightStorage == null)
|
||||||
{
|
{
|
||||||
this.blockLightStorage = new ChunkLightStorage(
|
this.blockLightStorage = ChunkLightStorage.createBlockLightStorage(this);
|
||||||
this.getMinBuildHeight(), this.getMaxBuildHeight(),
|
|
||||||
// positions above and below the handled area should be unlit
|
|
||||||
LodUtil.MIN_MC_LIGHT, LodUtil.MIN_MC_LIGHT);
|
|
||||||
}
|
}
|
||||||
return this.blockLightStorage;
|
return this.blockLightStorage;
|
||||||
}
|
}
|
||||||
|
public void setBlockLightStorage(ChunkLightStorage lightStorage) { this.blockLightStorage = lightStorage; }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -390,13 +414,11 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
{
|
{
|
||||||
if (this.skyLightStorage == null)
|
if (this.skyLightStorage == null)
|
||||||
{
|
{
|
||||||
this.skyLightStorage = new ChunkLightStorage(
|
this.skyLightStorage = ChunkLightStorage.createSkyLightStorage(this);
|
||||||
this.getMinBuildHeight(), this.getMaxBuildHeight(),
|
|
||||||
// positions above should be lit but positions below should be unlit
|
|
||||||
LodUtil.MAX_MC_LIGHT, LodUtil.MIN_MC_LIGHT);
|
|
||||||
}
|
}
|
||||||
return this.skyLightStorage;
|
return this.skyLightStorage;
|
||||||
}
|
}
|
||||||
|
public void setSkyLightStorage(ChunkLightStorage lightStorage) { this.skyLightStorage = lightStorage; }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -466,55 +488,6 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
return this.blockLightPosList;
|
return this.blockLightPosList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doNearbyChunksExist()
|
|
||||||
{
|
|
||||||
if (this.lightSource instanceof DhLitWorldGenRegion)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int dx = -1; dx <= 1; dx++)
|
|
||||||
{
|
|
||||||
for (int dz = -1; dz <= 1; dz++)
|
|
||||||
{
|
|
||||||
if (dx == 0 && dz == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (this.lightSource.getChunk(dx + this.chunk.getPos().x, dz + this.chunk.getPos().z, ChunkStatus.BIOMES, false) == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LevelReader getColorResolver() { return this.lightSource; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() { return this.chunk.getClass().getSimpleName() + this.chunk.getPos(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBlockStateWrapper getBlockState(int relX, int relY, int relZ)
|
|
||||||
{
|
|
||||||
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
|
|
||||||
|
|
||||||
BlockPos.MutableBlockPos blockPos = MUTABLE_BLOCK_POS_REF.get();
|
|
||||||
|
|
||||||
blockPos.setX(relX);
|
|
||||||
blockPos.setY(relY);
|
|
||||||
blockPos.setZ(relZ);
|
|
||||||
|
|
||||||
return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(blockPos), this.wrappedLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
|
|
||||||
|
|
||||||
|
|
||||||
public static void syncedUpdateClientLightStatus()
|
public static void syncedUpdateClientLightStatus()
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
@@ -574,64 +547,57 @@ public class ChunkWrapper implements IChunkWrapper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//================//
|
//===============//
|
||||||
// helper methods //
|
// other methods //
|
||||||
//================//
|
//===============//
|
||||||
|
|
||||||
/** used to prevent accidentally attempting to get/set values outside this chunk's boundaries */
|
@Override
|
||||||
private void throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(int x, int y, int z) throws IndexOutOfBoundsException
|
public boolean doNearbyChunksExist()
|
||||||
{
|
{
|
||||||
if (!RUN_RELATIVE_POS_INDEX_VALIDATION)
|
if (this.lightSource instanceof DhLitWorldGenRegion)
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int dx = -1; dx <= 1; dx++)
|
||||||
// FIXME +1 is to handle the fact that LodDataBuilder adds +1 to all block lighting calculations, also done in the constructor
|
|
||||||
int minHeight = this.getMinBuildHeight();
|
|
||||||
int maxHeight = this.getMaxBuildHeight() + 1;
|
|
||||||
|
|
||||||
if (x < 0 || x >= LodUtil.CHUNK_WIDTH
|
|
||||||
|| z < 0 || z >= LodUtil.CHUNK_WIDTH
|
|
||||||
|| y < minHeight || y > maxHeight)
|
|
||||||
{
|
{
|
||||||
String errorMessage = "Relative position [" + x + "," + y + "," + z + "] out of bounds. \n" +
|
for (int dz = -1; dz <= 1; dz++)
|
||||||
"X/Z must be between 0 and 15 (inclusive) \n" +
|
{
|
||||||
"Y must be between [" + minHeight + "] and [" + maxHeight + "] (inclusive).";
|
if (dx == 0 && dz == 0)
|
||||||
throw new IndexOutOfBoundsException(errorMessage);
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (this.lightSource.getChunk(dx + this.chunk.getPos().x, dz + this.chunk.getPos().z, ChunkStatus.BIOMES, false) == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStillValid() { return this.wrappedLevel.tryGetChunk(this.chunkPos) == this; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a 3D position into a 1D array index. <br><br>
|
|
||||||
*
|
|
||||||
* Source: <br>
|
|
||||||
* <a href="https://stackoverflow.com/questions/7367770/how-to-flatten-or-index-3d-array-in-1d-array">stackoverflow</a>
|
|
||||||
*/
|
|
||||||
public int relativeBlockPosToIndex(int xRel, int y, int zRel)
|
|
||||||
{
|
|
||||||
int yRel = y - this.getMinBuildHeight();
|
|
||||||
return (zRel * LodUtil.CHUNK_WIDTH * this.getHeight()) + (yRel * LodUtil.CHUNK_WIDTH) + xRel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a 3D position into a 1D array index. <br><br>
|
|
||||||
*
|
|
||||||
* Source: <br>
|
|
||||||
* <a href="https://stackoverflow.com/questions/7367770/how-to-flatten-or-index-3d-array-in-1d-array">stackoverflow</a>
|
|
||||||
*/
|
|
||||||
public DhBlockPos indexToRelativeBlockPos(int index)
|
|
||||||
{
|
|
||||||
final int zRel = index / (LodUtil.CHUNK_WIDTH * this.getHeight());
|
|
||||||
index -= (zRel * LodUtil.CHUNK_WIDTH * this.getHeight());
|
|
||||||
|
|
||||||
final int y = index / LodUtil.CHUNK_WIDTH;
|
//================//
|
||||||
final int yRel = y + this.getMinBuildHeight();
|
// base overrides //
|
||||||
|
//================//
|
||||||
|
|
||||||
final int xRel = index % LodUtil.CHUNK_WIDTH;
|
@Override
|
||||||
return new DhBlockPos(xRel, yRel, zRel);
|
public String toString() { return this.chunk.getClass().getSimpleName() + this.chunk.getPos(); }
|
||||||
}
|
|
||||||
|
|
||||||
|
//@Override
|
||||||
|
//public int hashCode()
|
||||||
|
//{
|
||||||
|
// if (this.blockBiomeHashCode == 0)
|
||||||
|
// {
|
||||||
|
// this.blockBiomeHashCode = this.getBlockBiomeHashCode();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return this.blockBiomeHashCode;
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-2
@@ -245,7 +245,7 @@ public class ClassicConfigGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Changelog button
|
// Changelog button
|
||||||
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() && Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE)
|
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() && !ModInfo.IS_DEV_BUILD) // we only have changelogs for stable builds
|
||||||
{
|
{
|
||||||
this.addBtn(new TexturedButtonWidget(
|
this.addBtn(new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
@@ -255,7 +255,13 @@ public class ClassicConfigGUI
|
|||||||
// texture UV Offset
|
// texture UV Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
0, new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"), 20, 20,
|
0,
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#endif
|
||||||
|
20, 20,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
(buttonWidget) -> {
|
(buttonWidget) -> {
|
||||||
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
||||||
|
|||||||
+2
-3
@@ -168,10 +168,9 @@ public class ChangelogScreen extends DhScreen
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
|
// render order matters, otherwise on 1.20.6+ the blurred background will render on top of the text
|
||||||
|
|
||||||
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
|
||||||
|
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
|
||||||
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
DhDrawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF); // Render title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
-12
@@ -42,15 +42,17 @@ public class UpdateModScreen extends DhScreen
|
|||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.newVersionID = newVersionID;
|
this.newVersionID = newVersionID;
|
||||||
|
|
||||||
switch (Config.Client.Advanced.AutoUpdater.updateBranch.get()) {
|
|
||||||
case STABLE:
|
EDhApiUpdateBranch updateBranch = EDhApiUpdateBranch.convertAutoToStableOrNightly(Config.Client.Advanced.AutoUpdater.updateBranch.get());
|
||||||
currentVer = ModInfo.VERSION;
|
if (updateBranch == EDhApiUpdateBranch.STABLE)
|
||||||
nextVer = ModrinthGetter.releaseNames.get(this.newVersionID);
|
{
|
||||||
break;
|
this.currentVer = ModInfo.VERSION;
|
||||||
case NIGHTLY:
|
this.nextVer = ModrinthGetter.releaseNames.get(this.newVersionID);
|
||||||
currentVer = ModJarInfo.Git_Commit.substring(0,7);
|
}
|
||||||
nextVer = this.newVersionID.substring(0,7);
|
else
|
||||||
break;
|
{
|
||||||
|
this.currentVer = ModJarInfo.Git_Commit.substring(0,7);
|
||||||
|
this.nextVer = this.newVersionID.substring(0,7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +75,13 @@ public class UpdateModScreen extends DhScreen
|
|||||||
// Offset
|
// Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
0, new ResourceLocation(ModInfo.ID, "logo.png"), 130, 65,
|
0,
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
new ResourceLocation(ModInfo.ID, "logo.png"),
|
||||||
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "logo.png"),
|
||||||
|
#endif
|
||||||
|
130, 65,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
// For now it goes to the client option by default
|
// For now it goes to the client option by default
|
||||||
(buttonWidget) -> System.out.println("Nice, you found an easter egg :)"), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
(buttonWidget) -> System.out.println("Nice, you found an easter egg :)"), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
||||||
@@ -88,7 +96,7 @@ public class UpdateModScreen extends DhScreen
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE)
|
if (!ModInfo.IS_DEV_BUILD)
|
||||||
{
|
{
|
||||||
this.addBtn(new TexturedButtonWidget(
|
this.addBtn(new TexturedButtonWidget(
|
||||||
// Where the button is on the screen
|
// Where the button is on the screen
|
||||||
@@ -98,7 +106,13 @@ public class UpdateModScreen extends DhScreen
|
|||||||
// Offset
|
// Offset
|
||||||
0, 0,
|
0, 0,
|
||||||
// Some textuary stuff
|
// Some textuary stuff
|
||||||
0, new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"), 20, 20,
|
0,
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#endif
|
||||||
|
20, 20,
|
||||||
// Create the button and tell it where to go
|
// Create the button and tell it where to go
|
||||||
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(new ChangelogScreen(this, this.newVersionID)), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(new ChangelogScreen(this, this.newVersionID)), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
|
||||||
// Add a title to the button
|
// Add a title to the button
|
||||||
|
|||||||
+10
-6
@@ -12,16 +12,20 @@ public class MinecraftDedicatedServerWrapper implements IMinecraftSharedWrapper
|
|||||||
private MinecraftDedicatedServerWrapper() { }
|
private MinecraftDedicatedServerWrapper() { }
|
||||||
public DedicatedServer dedicatedServer = null;
|
public DedicatedServer dedicatedServer = null;
|
||||||
@Override
|
@Override
|
||||||
public boolean isDedicatedServer()
|
public boolean isDedicatedServer() { return true; }
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public File getInstallationDirectory()
|
public File getInstallationDirectory()
|
||||||
{
|
{
|
||||||
if (dedicatedServer == null)
|
if (this.dedicatedServer == null)
|
||||||
|
{
|
||||||
throw new IllegalStateException("Trying to get Installation Direction before Dedicated server complete initialization!");
|
throw new IllegalStateException("Trying to get Installation Direction before Dedicated server complete initialization!");
|
||||||
return dedicatedServer.getServerDirectory();
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
return this.dedicatedServer.getServerDirectory();
|
||||||
|
#else
|
||||||
|
return this.dedicatedServer.getServerDirectory().toFile();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-3
@@ -212,15 +212,24 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
{
|
{
|
||||||
if (MC.level.dimensionType().hasSkyLight())
|
if (MC.level.dimensionType().hasSkyLight())
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
float frameTime;
|
||||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getBlockPosition(), MC.getFrameTime());
|
#if MC_VER < MC_1_21
|
||||||
|
frameTime = MC.getFrameTime();
|
||||||
#else
|
#else
|
||||||
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), MC.getFrameTime());
|
frameTime = MC.getTimer().getRealtimeDeltaTicks();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_17_1
|
||||||
|
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getBlockPosition(), frameTime);
|
||||||
|
#else
|
||||||
|
Vec3 colorValues = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), frameTime);
|
||||||
#endif
|
#endif
|
||||||
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
|
return new Color((float) colorValues.x, (float) colorValues.y, (float) colorValues.z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return new Color(0, 0, 0);
|
return new Color(0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+239
-179
@@ -35,6 +35,7 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|||||||
import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
import com.seibel.distanthorizons.core.util.objects.EventTimer;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
import com.seibel.distanthorizons.core.util.gridList.ArrayGridList;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvironmentWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvironmentWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
@@ -109,8 +110,6 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
new ConfigBasedLogger(LogManager.getLogger("LodWorldGen"),
|
||||||
() -> Config.Client.Advanced.Logging.logWorldGenLoadEvent.get());
|
() -> Config.Client.Advanced.Logging.logWorldGenLoadEvent.get());
|
||||||
|
|
||||||
//TODO: Make actual proper support for StarLight
|
|
||||||
|
|
||||||
public static class PerfCalculator
|
public static class PerfCalculator
|
||||||
{
|
{
|
||||||
private static final String[] TIME_NAMES = {
|
private static final String[] TIME_NAMES = {
|
||||||
@@ -294,6 +293,9 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=================//
|
||||||
|
// synchronization //
|
||||||
|
//=================//
|
||||||
|
|
||||||
public <T> T joinSync(CompletableFuture<T> future)
|
public <T> T joinSync(CompletableFuture<T> future)
|
||||||
{
|
{
|
||||||
@@ -344,7 +346,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
else if (event.hasTimeout(Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get(), TimeUnit.SECONDS))
|
else if (event.hasTimeout(Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get(), TimeUnit.SECONDS))
|
||||||
{
|
{
|
||||||
EVENT_LOGGER.error("Batching World Generator: " + event + " timed out and terminated!");
|
EVENT_LOGGER.error("Batching World Generator: " + event + " timed out and terminated! Please lower your CPU load.");
|
||||||
EVENT_LOGGER.info("Dump PrefEvent: " + event.timer);
|
EVENT_LOGGER.info("Dump PrefEvent: " + event.timer);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -368,31 +370,197 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ProtoChunk EmptyChunk(ServerLevel level, ChunkPos chunkPos)
|
|
||||||
|
|
||||||
|
//==================//
|
||||||
|
// world generation //
|
||||||
|
//==================//
|
||||||
|
|
||||||
|
public void generateLodFromList(GenerationEvent genEvent) throws InterruptedException
|
||||||
{
|
{
|
||||||
return new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
EVENT_LOGGER.debug("Lod Generate Event: " + genEvent.minPos);
|
||||||
#if MC_VER >= MC_1_17_1 , level #endif
|
|
||||||
#if MC_VER >= MC_1_18_2 , level.registryAccess().registryOrThrow(
|
|
||||||
#if MC_VER < MC_1_19_4
|
|
||||||
Registry.BIOME_REGISTRY
|
|
||||||
#else
|
|
||||||
Registries.BIOME
|
|
||||||
#endif
|
|
||||||
), null #endif
|
|
||||||
);
|
|
||||||
|
|
||||||
|
ArrayGridList<ChunkWrapper> chunkWrapperList;
|
||||||
|
DhLitWorldGenRegion region;
|
||||||
|
DummyLightEngine dummyLightEngine;
|
||||||
|
LightGetterAdaptor adaptor;
|
||||||
|
|
||||||
|
int borderSize = MaxBorderNeeded;
|
||||||
|
int refSize = genEvent.size + borderSize * 2;
|
||||||
|
int refPosX = genEvent.minPos.x - borderSize;
|
||||||
|
int refPosZ = genEvent.minPos.z - borderSize;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ArrayGridList<ChunkAccess> totalChunks;
|
||||||
|
|
||||||
|
adaptor = new LightGetterAdaptor(this.params.level);
|
||||||
|
dummyLightEngine = new DummyLightEngine(adaptor);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============================//
|
||||||
|
// try getting existing chunks //
|
||||||
|
//=============================//
|
||||||
|
|
||||||
|
HashMap<DhChunkPos, ChunkLightStorage> chunkSkyLightingByDhPos = new HashMap<>();
|
||||||
|
HashMap<DhChunkPos, ChunkLightStorage> chunkBlockLightingByDhPos = new HashMap<>();
|
||||||
|
IEmptyChunkGeneratorFunc emptyChunkGeneratorFunc = (int x, int z) ->
|
||||||
|
{
|
||||||
|
ChunkPos chunkPos = new ChunkPos(x, z);
|
||||||
|
DhChunkPos dhChunkPos = new DhChunkPos(x, z);
|
||||||
|
ChunkAccess newChunk = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get the chunk
|
||||||
|
CompoundTag chunkData = this.getChunkNbtData(chunkPos);
|
||||||
|
newChunk = this.loadOrMakeChunk(chunkPos, chunkData);
|
||||||
|
|
||||||
|
// get chunk lighting
|
||||||
|
ChunkLoader.CombinedChunkLightStorage combinedLights = ChunkLoader.readLight(newChunk, chunkData);
|
||||||
|
if (combinedLights != null)
|
||||||
|
{
|
||||||
|
chunkSkyLightingByDhPos.put(dhChunkPos, combinedLights.skyLightStorage);
|
||||||
|
chunkBlockLightingByDhPos.put(dhChunkPos, combinedLights.blockLightStorage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (RuntimeException loadChunkError)
|
||||||
|
{
|
||||||
|
// Continue...
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newChunk == null)
|
||||||
|
{
|
||||||
|
newChunk = new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||||
|
#if MC_VER >= MC_1_17_1 , this.params.level #endif
|
||||||
|
#if MC_VER >= MC_1_18_2 , this.params.biomes, null #endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return newChunk;
|
||||||
|
};
|
||||||
|
totalChunks = new ArrayGridList<>(refSize, (x, z) -> emptyChunkGeneratorFunc.generate(x + refPosX, z + refPosZ));
|
||||||
|
|
||||||
|
int radius = refSize / 2;
|
||||||
|
int centerX = refPosX + radius;
|
||||||
|
int centerZ = refPosZ + radius;
|
||||||
|
|
||||||
|
ChunkAccess centerChunk = totalChunks.stream().filter(chunk -> chunk.getPos().x == centerX && chunk.getPos().z == centerZ).findFirst().get();
|
||||||
|
|
||||||
|
genEvent.refreshTimeout();
|
||||||
|
region = new DhLitWorldGenRegion(
|
||||||
|
centerX, centerZ,
|
||||||
|
centerChunk,
|
||||||
|
this.params.level, dummyLightEngine, totalChunks,
|
||||||
|
ChunkStatus.STRUCTURE_STARTS, radius, emptyChunkGeneratorFunc);
|
||||||
|
adaptor.setRegion(region);
|
||||||
|
genEvent.threadedParam.makeStructFeat(region, this.params);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=======================//
|
||||||
|
// create chunk wrappers //
|
||||||
|
//=======================//
|
||||||
|
|
||||||
|
chunkWrapperList = new ArrayGridList<>(totalChunks.gridSize);
|
||||||
|
totalChunks.forEachPos((x, z) ->
|
||||||
|
{
|
||||||
|
ChunkAccess chunk = totalChunks.get(x, z);
|
||||||
|
if (chunk != null)
|
||||||
|
{
|
||||||
|
// wrap the chunk
|
||||||
|
ChunkWrapper chunkWrapper = new ChunkWrapper(chunk, region, this.serverlevel.getLevelWrapper());
|
||||||
|
chunkWrapperList.set(x, z, chunkWrapper);
|
||||||
|
|
||||||
|
// try getting the chunk lighting
|
||||||
|
if (chunkBlockLightingByDhPos.containsKey(chunkWrapper.getChunkPos()))
|
||||||
|
{
|
||||||
|
chunkWrapper.setBlockLightStorage(chunkBlockLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
||||||
|
chunkWrapper.setSkyLightStorage(chunkSkyLightingByDhPos.get(chunkWrapper.getChunkPos()));
|
||||||
|
chunkWrapper.setUseDhLighting(true);
|
||||||
|
chunkWrapper.setIsDhLightCorrect(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int k = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=================//
|
||||||
|
// generate chunks //
|
||||||
|
//=================//
|
||||||
|
|
||||||
|
this.generateDirect(genEvent, chunkWrapperList, borderSize, genEvent.targetGenerationStep, region);
|
||||||
|
genEvent.timer.nextEvent("cleanup");
|
||||||
|
}
|
||||||
|
catch (StepStructureStart.StructStartCorruptedException f)
|
||||||
|
{
|
||||||
|
genEvent.threadedParam.markAsInvalid();
|
||||||
|
throw (RuntimeException) f.getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayGridList<ChunkWrapper> finalGenChunks = GetCutoutFrom(chunkWrapperList, borderSize);
|
||||||
|
for (int offsetY = 0; offsetY < finalGenChunks.gridSize; offsetY++)
|
||||||
|
{
|
||||||
|
for (int offsetX = 0; offsetX < finalGenChunks.gridSize; offsetX++)
|
||||||
|
{
|
||||||
|
ChunkWrapper wrappedChunk = finalGenChunks.get(offsetX, offsetY);
|
||||||
|
ChunkAccess target = wrappedChunk.getChunk();
|
||||||
|
if (target instanceof LevelChunk)
|
||||||
|
{
|
||||||
|
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
||||||
|
((LevelChunk) target).setLoaded(true);
|
||||||
|
#else
|
||||||
|
((LevelChunk) target).loaded = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wrappedChunk.isLightCorrect())
|
||||||
|
{
|
||||||
|
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isFull = ChunkWrapper.getStatus(target) == ChunkStatus.FULL || target instanceof LevelChunk;
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
|
boolean isPartial = target.isOldNoiseGeneration();
|
||||||
|
#endif
|
||||||
|
if (isFull)
|
||||||
|
{
|
||||||
|
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
|
||||||
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
|
}
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
|
else if (isPartial)
|
||||||
|
{
|
||||||
|
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
|
||||||
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (ChunkWrapper.getStatus(target) == ChunkStatus.EMPTY)
|
||||||
|
{
|
||||||
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
genEvent.resultConsumer.accept(wrappedChunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
genEvent.timer.complete();
|
||||||
|
genEvent.refreshTimeout();
|
||||||
|
if (PREF_LOGGER.canMaybeLog())
|
||||||
|
{
|
||||||
|
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
|
||||||
|
PREF_LOGGER.infoInc("{}", genEvent.timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
private CompoundTag getChunkNbtData(ChunkPos chunkPos)
|
||||||
public ChunkAccess loadOrMakeChunk(ChunkPos chunkPos)
|
|
||||||
{
|
{
|
||||||
ServerLevel level = this.params.level;
|
ServerLevel level = this.params.level;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//====================//
|
|
||||||
// get the chunk data //
|
|
||||||
//====================//
|
|
||||||
|
|
||||||
CompoundTag chunkData = null;
|
CompoundTag chunkData = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -425,15 +593,15 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
LOAD_LOGGER.error("DistantHorizons: Couldn't load or make chunk " + chunkPos + ". Error: " + e.getMessage(), e);
|
LOAD_LOGGER.error("DistantHorizons: Couldn't load or make chunk " + chunkPos + ". Error: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return chunkData;
|
||||||
|
}
|
||||||
//========================//
|
private ChunkAccess loadOrMakeChunk(ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
// convert the chunk data //
|
{
|
||||||
//========================//
|
ServerLevel level = this.params.level;
|
||||||
|
|
||||||
if (chunkData == null)
|
if (chunkData == null)
|
||||||
{
|
{
|
||||||
return EmptyChunk(level, chunkPos);
|
return CreateEmptyChunk(level, chunkPos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -445,154 +613,28 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOAD_LOGGER.error(
|
LOAD_LOGGER.error(
|
||||||
"DistantHorizons: couldn't load or make chunk at ["+chunkPos+"]." +
|
"DistantHorizons: couldn't load or make chunk at ["+chunkPos+"]." +
|
||||||
"Please try optimizing your world to fix this issue. \n" +
|
"Please try optimizing your world to fix this issue. \n" +
|
||||||
"World optimization can be done from the singleplayer world selection screen.\n" +
|
"World optimization can be done from the singleplayer world selection screen.\n" +
|
||||||
"Error: ["+e.getMessage()+"]."
|
"Error: ["+e.getMessage()+"]."
|
||||||
, e);
|
, e);
|
||||||
|
|
||||||
return EmptyChunk(level, chunkPos);
|
return CreateEmptyChunk(level, chunkPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static ProtoChunk CreateEmptyChunk(ServerLevel level, ChunkPos chunkPos)
|
||||||
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, int border)
|
|
||||||
{
|
{
|
||||||
return new ArrayGridList<>(total, border, total.gridSize - border);
|
return new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
||||||
}
|
#if MC_VER >= MC_1_17_1 , level #endif
|
||||||
|
#if MC_VER >= MC_1_18_2 , level.registryAccess().registryOrThrow(
|
||||||
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step)
|
#if MC_VER < MC_1_19_4
|
||||||
{
|
Registry.BIOME_REGISTRY
|
||||||
return GetCutoutFrom(total, MaxBorderNeeded - BorderNeeded.get(step));
|
#else
|
||||||
}
|
Registries.BIOME
|
||||||
|
#endif
|
||||||
public void generateLodFromList(GenerationEvent genEvent) throws InterruptedException
|
), null #endif
|
||||||
{
|
);
|
||||||
EVENT_LOGGER.debug("Lod Generate Event: " + genEvent.minPos);
|
|
||||||
|
|
||||||
ArrayGridList<ChunkWrapper> chunkWrapperList;
|
|
||||||
DhLitWorldGenRegion region;
|
|
||||||
DummyLightEngine lightEngine;
|
|
||||||
LightGetterAdaptor adaptor;
|
|
||||||
|
|
||||||
int borderSize = MaxBorderNeeded;
|
|
||||||
int refSize = genEvent.size + borderSize * 2;
|
|
||||||
int refPosX = genEvent.minPos.x - borderSize;
|
|
||||||
int refPosZ = genEvent.minPos.z - borderSize;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ArrayGridList<ChunkAccess> totalChunks;
|
|
||||||
|
|
||||||
adaptor = new LightGetterAdaptor(this.params.level);
|
|
||||||
lightEngine = new DummyLightEngine(adaptor);
|
|
||||||
|
|
||||||
EmptyChunkGenerator generator = (int x, int z) ->
|
|
||||||
{
|
|
||||||
ChunkPos chunkPos = new ChunkPos(x, z);
|
|
||||||
ChunkAccess target = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
target = this.loadOrMakeChunk(chunkPos);
|
|
||||||
}
|
|
||||||
catch (RuntimeException e2)
|
|
||||||
{
|
|
||||||
// Continue...
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target == null)
|
|
||||||
{
|
|
||||||
target = new ProtoChunk(chunkPos, UpgradeData.EMPTY
|
|
||||||
#if MC_VER >= MC_1_17_1 , params.level #endif
|
|
||||||
#if MC_VER >= MC_1_18_2 , params.biomes, null #endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
};
|
|
||||||
|
|
||||||
totalChunks = new ArrayGridList<>(refSize, (x, z) -> generator.generate(x + refPosX, z + refPosZ));
|
|
||||||
|
|
||||||
genEvent.refreshTimeout();
|
|
||||||
region = new DhLitWorldGenRegion(params.level, lightEngine, totalChunks,
|
|
||||||
ChunkStatus.STRUCTURE_STARTS, refSize / 2, generator);
|
|
||||||
adaptor.setRegion(region);
|
|
||||||
genEvent.threadedParam.makeStructFeat(region, params);
|
|
||||||
|
|
||||||
|
|
||||||
chunkWrapperList = new ArrayGridList<>(totalChunks.gridSize);
|
|
||||||
totalChunks.forEachPos((x, z) ->
|
|
||||||
{
|
|
||||||
ChunkAccess chunk = totalChunks.get(x, z);
|
|
||||||
if (chunk != null)
|
|
||||||
{
|
|
||||||
chunkWrapperList.set(x, z, new ChunkWrapper(chunk, region, serverlevel.getLevelWrapper()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.generateDirect(genEvent, chunkWrapperList, borderSize, genEvent.targetGenerationStep, region);
|
|
||||||
genEvent.timer.nextEvent("cleanup");
|
|
||||||
}
|
|
||||||
catch (StepStructureStart.StructStartCorruptedException f)
|
|
||||||
{
|
|
||||||
genEvent.threadedParam.markAsInvalid();
|
|
||||||
throw (RuntimeException) f.getCause();
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayGridList<ChunkWrapper> finalGenChunks = GetCutoutFrom(chunkWrapperList, borderSize);
|
|
||||||
for (int offsetY = 0; offsetY < finalGenChunks.gridSize; offsetY++)
|
|
||||||
{
|
|
||||||
for (int offsetX = 0; offsetX < finalGenChunks.gridSize; offsetX++)
|
|
||||||
{
|
|
||||||
ChunkWrapper wrappedChunk = finalGenChunks.get(offsetX, offsetY);
|
|
||||||
ChunkAccess target = wrappedChunk.getChunk();
|
|
||||||
if (target instanceof LevelChunk)
|
|
||||||
{
|
|
||||||
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
|
|
||||||
((LevelChunk) target).setLoaded(true);
|
|
||||||
#else
|
|
||||||
((LevelChunk) target).loaded = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wrappedChunk.isLightCorrect())
|
|
||||||
{
|
|
||||||
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isFull = target.getStatus() == ChunkStatus.FULL || target instanceof LevelChunk;
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
boolean isPartial = target.isOldNoiseGeneration();
|
|
||||||
#endif
|
|
||||||
if (isFull)
|
|
||||||
{
|
|
||||||
LOAD_LOGGER.info("Detected full existing chunk at {}", target.getPos());
|
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
|
||||||
}
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
else if (isPartial)
|
|
||||||
{
|
|
||||||
LOAD_LOGGER.info("Detected old existing chunk at {}", target.getPos());
|
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (target.getStatus() == ChunkStatus.EMPTY)
|
|
||||||
{
|
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
genEvent.resultConsumer.accept(wrappedChunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
genEvent.timer.complete();
|
|
||||||
genEvent.refreshTimeout();
|
|
||||||
if (PREF_LOGGER.canMaybeLog())
|
|
||||||
{
|
|
||||||
genEvent.threadedParam.perf.recordEvent(genEvent.timer);
|
|
||||||
PREF_LOGGER.infoInc("{}", genEvent.timer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateDirect(
|
public void generateDirect(
|
||||||
@@ -694,7 +736,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
for (int i = 0; i < chunksToGenerate.size(); i++) // regular for loop since enhanced for loops increase GC pressure slightly
|
for (int i = 0; i < chunksToGenerate.size(); i++) // regular for loop since enhanced for loops increase GC pressure slightly
|
||||||
{
|
{
|
||||||
ChunkWrapper chunkWrapper = chunksToGenerate.get(i);
|
ChunkWrapper chunkWrapper = chunksToGenerate.get(i);
|
||||||
if (chunkWrapper.getChunk().getStatus() != ChunkStatus.EMPTY)
|
if (chunkWrapper.getStatus() != ChunkStatus.EMPTY)
|
||||||
{
|
{
|
||||||
iChunkWrapperList.add(chunkWrapper);
|
iChunkWrapperList.add(chunkWrapper);
|
||||||
}
|
}
|
||||||
@@ -715,19 +757,19 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
// if this isn't done everything else afterward may fail
|
// if this isn't done everything else afterward may fail
|
||||||
Heightmap.primeHeightmaps(((ChunkWrapper)centerChunk).getChunk(), ChunkStatus.FEATURES.heightmapsAfter());
|
Heightmap.primeHeightmaps(((ChunkWrapper)centerChunk).getChunk(), ChunkStatus.FEATURES.heightmapsAfter());
|
||||||
|
|
||||||
// populate the lighting
|
// pre-generated chunks should have lighting but new ones won't
|
||||||
DhLightingEngine.INSTANCE.lightChunk(centerChunk, iChunkWrapperList, maxSkyLight);
|
if (!centerChunk.isLightCorrect())
|
||||||
|
{
|
||||||
|
DhLightingEngine.INSTANCE.lightChunk(centerChunk, iChunkWrapperList, maxSkyLight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
genEvent.refreshTimeout();
|
genEvent.refreshTimeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, int border) { return new ArrayGridList<>(total, border, total.gridSize - border); }
|
||||||
|
private static <T> ArrayGridList<T> GetCutoutFrom(ArrayGridList<T> total, EDhApiWorldGenerationStep step) { return GetCutoutFrom(total, MaxBorderNeeded - BorderNeeded.get(step)); }
|
||||||
|
|
||||||
public interface EmptyChunkGenerator
|
|
||||||
{
|
|
||||||
ChunkAccess generate(int x, int z);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getEventCount() { return this.generationEventList.size(); }
|
public int getEventCount() { return this.generationEventList.size(); }
|
||||||
@@ -776,6 +818,12 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
return genEvent.future;
|
return genEvent.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper methods //
|
||||||
|
//================//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before code that may run for an extended period of time. <br>
|
* Called before code that may run for an extended period of time. <br>
|
||||||
* This is necessary to allow canceling world gen since waiting
|
* This is necessary to allow canceling world gen since waiting
|
||||||
@@ -789,4 +837,16 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IEmptyChunkGeneratorFunc
|
||||||
|
{
|
||||||
|
ChunkAccess generate(int x, int z);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+292
-129
@@ -22,9 +22,14 @@ package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.Dynamic;
|
import com.mojang.serialization.Dynamic;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||||
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
|
|
||||||
@@ -44,6 +49,7 @@ import net.minecraft.core.registries.Registries;
|
|||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.nbt.NbtOps;
|
import net.minecraft.nbt.NbtOps;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.*;
|
import net.minecraft.world.level.*;
|
||||||
@@ -79,6 +85,9 @@ import net.minecraft.world.level.material.Fluids;
|
|||||||
#if MC_VER == MC_1_20_6
|
#if MC_VER == MC_1_20_6
|
||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import net.minecraft.world.level.chunk.status.ChunkType;
|
import net.minecraft.world.level.chunk.status.ChunkType;
|
||||||
|
#elif MC_VER == MC_1_21
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
@@ -100,138 +109,13 @@ public class ChunkLoader
|
|||||||
private static final String FLUID_TICKS_TAG_PRE18 = "LiquidTicks";
|
private static final String FLUID_TICKS_TAG_PRE18 = "LiquidTicks";
|
||||||
private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER;
|
private static final ConfigBasedLogger LOGGER = BatchGenerationEnvironment.LOAD_LOGGER;
|
||||||
|
|
||||||
#if MC_VER >= MC_1_18_2
|
private static boolean lightingSectionErrorLogged = false;
|
||||||
private static BlendingData readBlendingData(CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
BlendingData blendingData = null;
|
|
||||||
if (chunkData.contains("blending_data", 10))
|
|
||||||
{
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
||||||
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
|
||||||
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
|
|
||||||
}
|
|
||||||
return blendingData;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
#if MC_VER >= MC_1_18_2
|
|
||||||
#if MC_VER < MC_1_19_4
|
|
||||||
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
|
||||||
#else
|
|
||||||
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registries.BIOME);
|
|
||||||
#endif
|
|
||||||
#if MC_VER < MC_1_18_2
|
|
||||||
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
|
||||||
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
|
||||||
#elif MC_VER < MC_1_19_2
|
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
|
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
|
||||||
#else
|
|
||||||
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
|
||||||
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
int i = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
|
||||||
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
|
|
||||||
|
|
||||||
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
|
||||||
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
|
||||||
ListTag tagSections = chunkData.getList("Sections", 10);
|
|
||||||
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
|
|
||||||
|
|
||||||
for (int j = 0; j < tagSections.size(); ++j)
|
//============//
|
||||||
{
|
// read chunk //
|
||||||
CompoundTag tagSection = tagSections.getCompound(j);
|
//============//
|
||||||
int sectionYPos = tagSection.getByte("Y");
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
|
||||||
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
|
||||||
{
|
|
||||||
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
|
||||||
levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
|
|
||||||
tagSection.getLongArray("BlockStates"));
|
|
||||||
levelChunkSection.recalcBlockCounts();
|
|
||||||
if (!levelChunkSection.isEmpty())
|
|
||||||
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
|
||||||
= levelChunkSection;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
|
||||||
if (sectionId >= 0 && sectionId < chunkSections.length)
|
|
||||||
{
|
|
||||||
PalettedContainer<BlockState> blockStateContainer;
|
|
||||||
#if MC_VER < MC_1_18_2
|
|
||||||
PalettedContainer<Biome> biomeContainer;
|
|
||||||
#else
|
|
||||||
PalettedContainer<Holder<Biome>> biomeContainer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
blockStateContainer = tagSection.contains("block_states", 10)
|
|
||||||
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string))
|
|
||||||
#if MC_VER < MC_1_20_6 .getOrThrow(false, LOGGER::error) #else .getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null)) #endif
|
|
||||||
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_18_2
|
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
|
||||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
|
|
||||||
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
|
||||||
#else
|
|
||||||
|
|
||||||
biomeContainer = tagSection.contains("biomes", 10)
|
|
||||||
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, i, (String) string))
|
|
||||||
#if MC_VER < MC_1_20_6 .getOrThrow(false, LOGGER::error) #else .getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null)) #endif
|
|
||||||
: new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
|
||||||
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
|
||||||
#else
|
|
||||||
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
return chunkSections;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
|
|
||||||
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
|
||||||
{
|
|
||||||
String heightmap = type.getSerializationKey();
|
|
||||||
if (tagHeightmaps.contains(heightmap, 12))
|
|
||||||
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
|
||||||
}
|
|
||||||
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
|
||||||
{
|
|
||||||
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
|
||||||
for (int n = 0; n < tagPostProcessings.size(); ++n)
|
|
||||||
{
|
|
||||||
ListTag listTag3 = tagPostProcessings.getList(n);
|
|
||||||
for (int o = 0; o < listTag3.size(); ++o)
|
|
||||||
{
|
|
||||||
chunk.addPackedPostProcess(listTag3.getShort(o), n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType #else ChunkType #endif readChunkType(CompoundTag tagLevel)
|
|
||||||
{
|
|
||||||
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
|
|
||||||
if (chunkStatus != null)
|
|
||||||
{
|
|
||||||
return chunkStatus.getChunkType();
|
|
||||||
}
|
|
||||||
|
|
||||||
return #if MC_VER < MC_1_20_6 ChunkStatus.ChunkType.PROTOCHUNK; #else ChunkType.PROTOCHUNK; #endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LevelChunk read(WorldGenLevel level, ChunkPos chunkPos, CompoundTag chunkData)
|
public static LevelChunk read(WorldGenLevel level, ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
{
|
{
|
||||||
@@ -349,11 +233,290 @@ public class ChunkLoader
|
|||||||
readPostPocessings(chunk, chunkData);
|
readPostPocessings(chunk, chunkData);
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
private static LevelChunkSection[] readSections(LevelAccessor level, ChunkPos chunkPos, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
|
#if MC_VER < MC_1_19_4
|
||||||
|
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
|
#else
|
||||||
|
Registry<Biome> biomes = level.registryAccess().registryOrThrow(Registries.BIOME);
|
||||||
|
#endif
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
Codec<PalettedContainer<Biome>> biomeCodec = PalettedContainer.codec(
|
||||||
|
biomes, biomes.byNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getOrThrow(Biomes.PLAINS));
|
||||||
|
#elif MC_VER < MC_1_19_2
|
||||||
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codec(
|
||||||
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||||
|
#else
|
||||||
|
Codec<PalettedContainer<Holder<Biome>>> biomeCodec = PalettedContainer.codecRW(
|
||||||
|
biomes.asHolderIdMap(), biomes.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomes.getHolderOrThrow(Biomes.PLAINS));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
int i = #if MC_VER < MC_1_17_1 16; #else level.getSectionsCount(); #endif
|
||||||
|
LevelChunkSection[] chunkSections = new LevelChunkSection[i];
|
||||||
|
|
||||||
|
boolean isLightOn = chunkData.getBoolean("isLightOn");
|
||||||
|
boolean hasSkyLight = level.dimensionType().hasSkyLight();
|
||||||
|
ListTag tagSections = chunkData.getList("Sections", 10);
|
||||||
|
if (tagSections.isEmpty()) tagSections = chunkData.getList("sections", 10);
|
||||||
|
|
||||||
|
for (int j = 0; j < tagSections.size(); ++j)
|
||||||
|
{
|
||||||
|
CompoundTag tagSection = tagSections.getCompound(j);
|
||||||
|
int sectionYPos = tagSection.getByte("Y");
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
if (tagSection.contains("Palette", 9) && tagSection.contains("BlockStates", 12))
|
||||||
|
{
|
||||||
|
LevelChunkSection levelChunkSection = new LevelChunkSection(sectionYPos << 4);
|
||||||
|
levelChunkSection.getStates().read(tagSection.getList("Palette", 10),
|
||||||
|
tagSection.getLongArray("BlockStates"));
|
||||||
|
levelChunkSection.recalcBlockCounts();
|
||||||
|
if (!levelChunkSection.isEmpty())
|
||||||
|
chunkSections[#if MC_VER < MC_1_17_1 sectionYPos #else level.getSectionIndexFromSectionY(sectionYPos) #endif ]
|
||||||
|
= levelChunkSection;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int sectionId = level.getSectionIndexFromSectionY(sectionYPos);
|
||||||
|
if (sectionId >= 0 && sectionId < chunkSections.length)
|
||||||
|
{
|
||||||
|
PalettedContainer<BlockState> blockStateContainer;
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
PalettedContainer<Biome> biomeContainer;
|
||||||
|
#else
|
||||||
|
PalettedContainer<Holder<Biome>> biomeContainer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
blockStateContainer = tagSection.contains("block_states", 10)
|
||||||
|
? BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, tagSection.getCompound("block_states")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string))
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
.getOrThrow(false, LOGGER::error)
|
||||||
|
#else
|
||||||
|
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||||
|
#endif
|
||||||
|
: new PalettedContainer<BlockState>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_18_2
|
||||||
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
|
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, sectionYPos, string)).getOrThrow(false, LOGGER::error)
|
||||||
|
: new PalettedContainer<Biome>(biomes, biomes.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
|
#else
|
||||||
|
|
||||||
|
biomeContainer = tagSection.contains("biomes", 10)
|
||||||
|
? biomeCodec.parse(NbtOps.INSTANCE, tagSection.getCompound("biomes")).promotePartial(string -> logErrors(chunkPos, i, (String) string))
|
||||||
|
#if MC_VER < MC_1_20_6
|
||||||
|
.getOrThrow(false, LOGGER::error)
|
||||||
|
#else
|
||||||
|
.getOrThrow((message) -> (RuntimeException) LOGGER.errorAndThrow(message, null))
|
||||||
|
#endif
|
||||||
|
: new PalettedContainer<Holder<Biome>>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
chunkSections[sectionId] = new LevelChunkSection(sectionYPos, blockStateContainer, biomeContainer);
|
||||||
|
#else
|
||||||
|
chunkSections[sectionId] = new LevelChunkSection(blockStateContainer, biomeContainer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
return chunkSections;
|
||||||
|
}
|
||||||
|
private static
|
||||||
|
#if MC_VER < MC_1_20_6 ChunkStatus.ChunkType
|
||||||
|
#elif MC_VER < MC_1_21 ChunkType
|
||||||
|
#else ChunkType #endif
|
||||||
|
readChunkType(CompoundTag tagLevel)
|
||||||
|
{
|
||||||
|
ChunkStatus chunkStatus = ChunkStatus.byName(tagLevel.getString("Status"));
|
||||||
|
if (chunkStatus != null)
|
||||||
|
{
|
||||||
|
return chunkStatus.getChunkType();
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
#if MC_VER <= MC_1_20_4 ChunkStatus.ChunkType.PROTOCHUNK;
|
||||||
|
#else ChunkType.PROTOCHUNK; #endif
|
||||||
|
}
|
||||||
|
private static void readHeightmaps(LevelChunk chunk, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
CompoundTag tagHeightmaps = chunkData.getCompound("Heightmaps");
|
||||||
|
for (Heightmap.Types type : ChunkStatus.FULL.heightmapsAfter())
|
||||||
|
{
|
||||||
|
String heightmap = type.getSerializationKey();
|
||||||
|
if (tagHeightmaps.contains(heightmap, 12))
|
||||||
|
chunk.setHeightmap(type, tagHeightmaps.getLongArray(heightmap));
|
||||||
|
}
|
||||||
|
Heightmap.primeHeightmaps(chunk, ChunkStatus.FULL.heightmapsAfter());
|
||||||
|
}
|
||||||
|
private static void readPostPocessings(LevelChunk chunk, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
ListTag tagPostProcessings = chunkData.getList("PostProcessing", 9);
|
||||||
|
for (int n = 0; n < tagPostProcessings.size(); ++n)
|
||||||
|
{
|
||||||
|
ListTag listTag3 = tagPostProcessings.getList(n);
|
||||||
|
for (int o = 0; o < listTag3.size(); ++o)
|
||||||
|
{
|
||||||
|
chunk.addPackedPostProcess(listTag3.getShort(o), n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if MC_VER >= MC_1_18_2
|
||||||
|
private static BlendingData readBlendingData(CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
BlendingData blendingData = null;
|
||||||
|
if (chunkData.contains("blending_data", 10))
|
||||||
|
{
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
Dynamic<CompoundTag> blendingDataTag = new Dynamic(NbtOps.INSTANCE, chunkData.getCompound("blending_data"));
|
||||||
|
blendingData = BlendingData.CODEC.parse(blendingDataTag).resultOrPartial(LOGGER::error).orElse(null);
|
||||||
|
}
|
||||||
|
return blendingData;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=====================//
|
||||||
|
// read chunk lighting //
|
||||||
|
//=====================//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://minecraft.wiki/w/Chunk_format
|
||||||
|
*/
|
||||||
|
public static CombinedChunkLightStorage readLight(ChunkAccess chunk, CompoundTag chunkData)
|
||||||
|
{
|
||||||
|
#if MC_VER <= MC_1_17_1
|
||||||
|
// MC 1.16 and 1.17 doesn't have the necessary NBT info
|
||||||
|
return null;
|
||||||
|
#else
|
||||||
|
|
||||||
|
CombinedChunkLightStorage combinedStorage = new CombinedChunkLightStorage(ChunkWrapper.getMinBuildHeight(chunk), ChunkWrapper.getMaxBuildHeight(chunk));
|
||||||
|
ChunkLightStorage blockLightStorage = combinedStorage.blockLightStorage;
|
||||||
|
ChunkLightStorage skyLightStorage = combinedStorage.skyLightStorage;
|
||||||
|
|
||||||
|
boolean foundSkyLight = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===================//
|
||||||
|
// get NBT tags info //
|
||||||
|
//===================//
|
||||||
|
|
||||||
|
Tag chunkSectionTags = chunkData.get("sections");
|
||||||
|
if (chunkSectionTags == null)
|
||||||
|
{
|
||||||
|
if (!lightingSectionErrorLogged)
|
||||||
|
{
|
||||||
|
lightingSectionErrorLogged = true;
|
||||||
|
LOGGER.error("No sections found for chunk at pos ["+chunk.getPos()+"] chunk data may be out of date.");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (!(chunkSectionTags instanceof ListTag))
|
||||||
|
{
|
||||||
|
if (!lightingSectionErrorLogged)
|
||||||
|
{
|
||||||
|
lightingSectionErrorLogged = true;
|
||||||
|
LOGGER.error("Chunk section tag list have unexpected type ["+chunkSectionTags.getClass().getName()+"], expected ["+ListTag.class.getName()+"].");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ListTag chunkSectionListTag = (ListTag) chunkSectionTags;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===================//
|
||||||
|
// get lighting info //
|
||||||
|
//===================//
|
||||||
|
|
||||||
|
for (int sectionIndex = 0; sectionIndex < chunkSectionListTag.size(); sectionIndex++)
|
||||||
|
{
|
||||||
|
Tag chunkSectionTag = chunkSectionListTag.get(sectionIndex);
|
||||||
|
if (!(chunkSectionTag instanceof CompoundTag))
|
||||||
|
{
|
||||||
|
if (!lightingSectionErrorLogged)
|
||||||
|
{
|
||||||
|
lightingSectionErrorLogged = true;
|
||||||
|
LOGGER.error("Chunk section tag has an unexpected type ["+chunkSectionTag.getClass().getName()+"], expected ["+CompoundTag.class.getName()+"].");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
CompoundTag chunkSectionCompoundTag = (CompoundTag) chunkSectionTag;
|
||||||
|
|
||||||
|
|
||||||
|
// if null all lights = 0
|
||||||
|
byte[] blockLightNibbleArray = chunkSectionCompoundTag.getByteArray("BlockLight");
|
||||||
|
byte[] skyLightNibbleArray = chunkSectionCompoundTag.getByteArray("SkyLight");
|
||||||
|
|
||||||
|
// if any sky light was found then all lights above will be max brightness
|
||||||
|
if (skyLightNibbleArray.length != 0)
|
||||||
|
{
|
||||||
|
foundSkyLight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
|
||||||
|
{
|
||||||
|
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
||||||
|
{
|
||||||
|
// chunk sections are also 16 blocks tall
|
||||||
|
for (int relY = 0; relY < LodUtil.CHUNK_WIDTH; relY++)
|
||||||
|
{
|
||||||
|
int blockPosIndex = relY*16*16 + relZ*16 + relX;
|
||||||
|
byte blockLight = (blockLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(blockLightNibbleArray, blockPosIndex);
|
||||||
|
byte skyLight = (skyLightNibbleArray.length == 0) ? 0 : getNibbleAtIndex(skyLightNibbleArray, blockPosIndex);
|
||||||
|
if (skyLightNibbleArray.length == 0 && foundSkyLight)
|
||||||
|
{
|
||||||
|
skyLight = LodUtil.MAX_MC_LIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int y = relY + (sectionIndex * LodUtil.CHUNK_WIDTH) + ChunkWrapper.getMinBuildHeight(chunk);
|
||||||
|
blockLightStorage.set(relX, y, relZ, blockLight);
|
||||||
|
skyLightStorage.set(relX, y, relZ, skyLight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return combinedStorage;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/** source: https://minecraft.wiki/w/Chunk_format#Block_Format */
|
||||||
|
private static byte getNibbleAtIndex(byte[] arr, int index)
|
||||||
|
{
|
||||||
|
if (index % 2 == 0)
|
||||||
|
{
|
||||||
|
return (byte)(arr[index/2] & 0x0F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (byte)((arr[index/2]>>4) & 0x0F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void logErrors(ChunkPos chunkPos, int i, String string)
|
private static void logErrors(ChunkPos chunkPos, int i, String string)
|
||||||
{
|
{
|
||||||
LOGGER.error("Distant Horizons: Recoverable errors when loading section [" + chunkPos.x + ", " + i + ", " + chunkPos.z + "]: " + string);
|
LOGGER.error("Distant Horizons: Recoverable errors when loading section [" + chunkPos.x + ", " + i + ", " + chunkPos.z + "]: " + string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
public static class CombinedChunkLightStorage
|
||||||
|
{
|
||||||
|
public ChunkLightStorage blockLightStorage;
|
||||||
|
public ChunkLightStorage skyLightStorage;
|
||||||
|
|
||||||
|
public CombinedChunkLightStorage(int minY, int maxY)
|
||||||
|
{
|
||||||
|
this.blockLightStorage = ChunkLightStorage.createBlockLightStorage(minY, maxY);
|
||||||
|
this.skyLightStorage = ChunkLightStorage.createSkyLightStorage(minY, maxY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_21
|
||||||
|
|
||||||
|
import net.minecraft.server.level.GenerationChunkHolder;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
|
||||||
|
public class DhGenerationChunkHolder extends GenerationChunkHolder
|
||||||
|
{
|
||||||
|
|
||||||
|
public DhGenerationChunkHolder(ChunkPos pos)
|
||||||
|
{
|
||||||
|
super(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTicketLevel() { return 0; }
|
||||||
|
@Override
|
||||||
|
public int getQueueLevel() { return 0; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+31
-6
@@ -20,9 +20,10 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
@@ -59,7 +60,13 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
|||||||
#if MC_VER <= MC_1_20_4
|
#if MC_VER <= MC_1_20_4
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
#else
|
#else
|
||||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.*;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER == MC_1_21
|
||||||
|
import net.minecraft.util.StaticCache2D;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import net.minecraft.server.level.GenerationChunkHolder;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -71,7 +78,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
|
|
||||||
|
|
||||||
public final DummyLightEngine lightEngine;
|
public final DummyLightEngine lightEngine;
|
||||||
public final BatchGenerationEnvironment.EmptyChunkGenerator generator;
|
public final BatchGenerationEnvironment.IEmptyChunkGeneratorFunc generator;
|
||||||
public final int writeRadius;
|
public final int writeRadius;
|
||||||
public final int size;
|
public final int size;
|
||||||
|
|
||||||
@@ -112,11 +119,29 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
|
|
||||||
|
|
||||||
public DhLitWorldGenRegion(
|
public DhLitWorldGenRegion(
|
||||||
|
int centerChunkX, int centerChunkZ,
|
||||||
|
ChunkAccess centerChunk,
|
||||||
ServerLevel serverLevel, DummyLightEngine lightEngine,
|
ServerLevel serverLevel, DummyLightEngine lightEngine,
|
||||||
List<ChunkAccess> chunkList, ChunkStatus chunkStatus, int writeRadius,
|
List<ChunkAccess> chunkList, ChunkStatus chunkStatus, int writeRadius,
|
||||||
BatchGenerationEnvironment.EmptyChunkGenerator generator)
|
BatchGenerationEnvironment.IEmptyChunkGeneratorFunc generator)
|
||||||
{
|
{
|
||||||
super(serverLevel, chunkList #if MC_VER >= MC_1_17_1 , chunkStatus, writeRadius #endif );
|
#if MC_VER == MC_1_16_5
|
||||||
|
super(serverLevel, chunkList);
|
||||||
|
#elif MC_VER < MC_1_21
|
||||||
|
super(serverLevel, chunkList, chunkStatus, writeRadius);
|
||||||
|
#else
|
||||||
|
super(serverLevel,
|
||||||
|
StaticCache2D.create(
|
||||||
|
centerChunkX, centerChunkZ,
|
||||||
|
writeRadius * 2, (x,z) -> new DhGenerationChunkHolder(new ChunkPos(x, z))),
|
||||||
|
new ChunkStep(chunkStatus,
|
||||||
|
// reverse is needed because MC uses the index of the chunkStatus to determine how many items are in the list instead of the actual list count
|
||||||
|
new ChunkDependencies(ImmutableList.copyOf(ChunkStatus.getStatusList()).reverse()),
|
||||||
|
new ChunkDependencies(ImmutableList.copyOf(ChunkStatus.getStatusList()).reverse()),
|
||||||
|
writeRadius, (WorldGenContext var1, ChunkStep var2, StaticCache2D<GenerationChunkHolder> var3, ChunkAccess var4) -> null),
|
||||||
|
centerChunk);
|
||||||
|
|
||||||
|
#endif
|
||||||
this.firstPos = chunkList.get(0).getPos();
|
this.firstPos = chunkList.get(0).getPos();
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
this.lightEngine = lightEngine;
|
this.lightEngine = lightEngine;
|
||||||
@@ -280,7 +305,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
|
|||||||
private ChunkAccess getChunkAccess(int chunkX, int chunkZ, ChunkStatus chunkStatus, boolean returnNonNull)
|
private ChunkAccess getChunkAccess(int chunkX, int chunkZ, ChunkStatus chunkStatus, boolean returnNonNull)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = this.superHasChunk(chunkX, chunkZ) ? this.superGetChunk(chunkX, chunkZ) : null;
|
ChunkAccess chunk = this.superHasChunk(chunkX, chunkZ) ? this.superGetChunk(chunkX, chunkZ) : null;
|
||||||
if (chunk != null && chunk.getStatus().isOrAfter(chunkStatus))
|
if (chunk != null && ChunkWrapper.getStatus(chunk).isOrAfter(chunkStatus))
|
||||||
{
|
{
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-8
@@ -56,29 +56,39 @@ public final class StepBiomes
|
|||||||
List<ChunkWrapper> chunkWrappers)
|
List<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (!chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
{
|
||||||
chunksToDo.add(chunk);
|
#if MC_VER < MC_1_21
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
chunksToDo.add(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
{
|
{
|
||||||
// System.out.println("StepBiomes: "+chunk.getPos());
|
// System.out.println("StepBiomes: "+chunk.getPos());
|
||||||
#if MC_VER < MC_1_18_2
|
#if MC_VER < MC_1_18_2
|
||||||
environment.params.generator.createBiomes(environment.params.biomes, chunk);
|
this.environment.params.generator.createBiomes(this.environment.params.biomes, chunk);
|
||||||
#elif MC_VER < MC_1_19_2
|
#elif MC_VER < MC_1_19_2
|
||||||
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#elif MC_VER < MC_1_19_4
|
#elif MC_VER < MC_1_19_4
|
||||||
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, environment.params.randomState, Blender.of(worldGenRegion),
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.biomes, Runnable::run, this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#elif MC_VER < MC_1_21
|
||||||
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(Runnable::run, this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#else
|
#else
|
||||||
chunk = environment.joinSync(environment.params.generator.createBiomes(Runnable::run, environment.params.randomState, Blender.of(worldGenRegion),
|
chunk = this.environment.joinSync(this.environment.params.generator.createBiomes(this.environment.params.randomState, Blender.of(worldGenRegion),
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -59,14 +59,14 @@ public final class StepFeatures
|
|||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS))
|
if (!chunkWrapper.getStatus().isOrAfter(STATUS)
|
||||||
{
|
&& chunk instanceof ProtoChunk)
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chunk instanceof ProtoChunk)
|
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+17
-6
@@ -58,13 +58,21 @@ public final class StepNoise
|
|||||||
List<ChunkWrapper> chunkWrappers)
|
List<ChunkWrapper> chunkWrappers)
|
||||||
{
|
{
|
||||||
|
|
||||||
ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
|
ArrayList<ChunkAccess> chunksToDo = new ArrayList<>();
|
||||||
|
|
||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,15 +80,18 @@ public final class StepNoise
|
|||||||
{
|
{
|
||||||
// System.out.println("StepNoise: "+chunk.getPos());
|
// System.out.println("StepNoise: "+chunk.getPos());
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
environment.params.generator.fillFromNoise(worldGenRegion, tParams.structFeat, chunk);
|
this.environment.params.generator.fillFromNoise(worldGenRegion, tParams.structFeat, chunk);
|
||||||
#elif MC_VER < MC_1_18_2
|
#elif MC_VER < MC_1_18_2
|
||||||
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run,
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run,
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#elif MC_VER < MC_1_19_2
|
#elif MC_VER < MC_1_19_2
|
||||||
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
|
||||||
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
|
#elif MC_VER < MC_1_21
|
||||||
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion), this.environment.params.randomState,
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#else
|
#else
|
||||||
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion), environment.params.randomState,
|
chunk = this.environment.joinSync(this.environment.params.generator.fillFromNoise(Blender.of(worldGenRegion), this.environment.params.randomState,
|
||||||
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
|
||||||
#endif
|
#endif
|
||||||
UncheckedInterruptedException.throwIfInterrupted();
|
UncheckedInterruptedException.throwIfInterrupted();
|
||||||
|
|||||||
+9
-3
@@ -59,9 +59,15 @@ public final class StepStructureReference
|
|||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (!chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
{
|
||||||
chunksToDo.add(chunk);
|
#if MC_VER < MC_1_21
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
chunksToDo.add(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
|
|||||||
+5
-1
@@ -76,9 +76,13 @@ public final class StepStructureStart
|
|||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (!chunk.getStatus().isOrAfter(STATUS))
|
if (!chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
{
|
{
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
chunksToDo.add(chunk);
|
chunksToDo.add(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -58,9 +58,16 @@ public final class StepSurface
|
|||||||
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
for (ChunkWrapper chunkWrapper : chunkWrappers)
|
||||||
{
|
{
|
||||||
ChunkAccess chunk = chunkWrapper.getChunk();
|
ChunkAccess chunk = chunkWrapper.getChunk();
|
||||||
if (chunk.getStatus().isOrAfter(STATUS)) continue;
|
if (!chunkWrapper.getStatus().isOrAfter(STATUS))
|
||||||
((ProtoChunk) chunk).setStatus(STATUS);
|
{
|
||||||
chunksToDo.add(chunk);
|
#if MC_VER < MC_1_21
|
||||||
|
((ProtoChunk) chunk).setStatus(STATUS);
|
||||||
|
#else
|
||||||
|
((ProtoChunk) chunk).setPersistedStatus(STATUS);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
chunksToDo.add(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChunkAccess chunk : chunksToDo)
|
for (ChunkAccess chunk : chunksToDo)
|
||||||
|
|||||||
+1
-1
Submodule coreSubProjects updated: 76f28e648c...28e1eaae77
@@ -208,7 +208,12 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
this.clientApi.renderLods(ClientLevelWrapper.getWrapper(renderContext.world()),
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
projectionMatrix,
|
projectionMatrix,
|
||||||
renderContext.tickDelta());
|
#if MC_VER < MC_1_21
|
||||||
|
renderContext.tickDelta()
|
||||||
|
#else
|
||||||
|
renderContext.tickCounter().getGameTimeDeltaTicks()
|
||||||
|
#endif
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Debug keyboard event
|
// Debug keyboard event
|
||||||
|
|||||||
+6
-1
@@ -120,7 +120,12 @@ public class MixinLevelRenderer
|
|||||||
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level),
|
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level),
|
||||||
mcModelViewMatrix,
|
mcModelViewMatrix,
|
||||||
mcProjectionMatrix,
|
mcProjectionMatrix,
|
||||||
Minecraft.getInstance().getFrameTime());
|
#if MC_VER < MC_1_21
|
||||||
|
Minecraft.getInstance().getFrameTime()
|
||||||
|
#else
|
||||||
|
Minecraft.getInstance().getTimer().getRealtimeDeltaTicks()
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME completely disables rendering when sodium is installed
|
// FIXME completely disables rendering when sodium is installed
|
||||||
|
|||||||
+15
-4
@@ -8,6 +8,7 @@ import com.seibel.distanthorizons.core.jar.installer.GitlabGetter;
|
|||||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||||
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
@@ -87,13 +88,23 @@ public class MixinMinecraft
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
runnable = () -> {
|
runnable = () ->
|
||||||
|
{
|
||||||
|
String versionId;
|
||||||
|
EDhApiUpdateBranch updateBranch = EDhApiUpdateBranch.convertAutoToStableOrNightly(Config.Client.Advanced.AutoUpdater.updateBranch.get());
|
||||||
|
if (updateBranch == EDhApiUpdateBranch.STABLE)
|
||||||
|
{
|
||||||
|
versionId = ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
versionId = GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha");
|
||||||
|
}
|
||||||
|
|
||||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||||
// TODO: Change to runnable, instead of tittle screen
|
// TODO: Change to runnable, instead of tittle screen
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE
|
versionId
|
||||||
? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion())
|
|
||||||
: GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-6
@@ -23,16 +23,13 @@ import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import net.minecraft.client.gui.screens.OptionsScreen;
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
@@ -41,11 +38,20 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
#if MC_VER == MC_1_20_6
|
#if MC_VER >= MC_1_20_6
|
||||||
import net.minecraft.client.gui.layouts.LinearLayout;
|
import net.minecraft.client.gui.layouts.LinearLayout;
|
||||||
import net.minecraft.client.gui.layouts.HeaderAndFooterLayout;
|
import net.minecraft.client.gui.layouts.HeaderAndFooterLayout;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
import net.minecraft.client.gui.screens.OptionsScreen;
|
||||||
|
#else
|
||||||
|
import net.minecraft.client.gui.screens.options.OptionsScreen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a button to the menu to goto the config
|
* Adds a button to the menu to goto the config
|
||||||
*
|
*
|
||||||
@@ -57,13 +63,18 @@ public class MixinOptionsScreen extends Screen
|
|||||||
{
|
{
|
||||||
/** Texture used for the config opening button */
|
/** Texture used for the config opening button */
|
||||||
@Unique
|
@Unique
|
||||||
private static final ResourceLocation ICON_TEXTURE = new ResourceLocation(ModInfo.ID, "textures/gui/button.png");
|
private static final ResourceLocation ICON_TEXTURE =
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
new ResourceLocation(ModInfo.ID, "textures/gui/button.png");
|
||||||
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/button.png");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private TexturedButtonWidget optionsButton = null;
|
private TexturedButtonWidget optionsButton = null;
|
||||||
|
|
||||||
#if MC_VER == MC_1_20_6
|
#if MC_VER >= MC_1_20_6
|
||||||
@Shadow
|
@Shadow
|
||||||
@Final
|
@Final
|
||||||
protected HeaderAndFooterLayout layout;
|
protected HeaderAndFooterLayout layout;
|
||||||
|
|||||||
+3
-2
@@ -5,7 +5,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IBCLibAcces
|
|||||||
#elif MC_VER == MC_1_18_2
|
#elif MC_VER == MC_1_18_2
|
||||||
import ru.bclib.config.ClientConfig;
|
import ru.bclib.config.ClientConfig;
|
||||||
import ru.bclib.config.Configs;
|
import ru.bclib.config.Configs;
|
||||||
#else
|
#elif MC_VER < MC_1_21
|
||||||
import org.betterx.bclib.config.ClientConfig;
|
import org.betterx.bclib.config.ClientConfig;
|
||||||
import org.betterx.bclib.config.Configs;
|
import org.betterx.bclib.config.Configs;
|
||||||
#endif
|
#endif
|
||||||
@@ -17,7 +17,8 @@ public class BCLibAccessor implements IBCLibAccessor
|
|||||||
|
|
||||||
public void setRenderCustomFog(boolean newValue)
|
public void setRenderCustomFog(boolean newValue)
|
||||||
{
|
{
|
||||||
#if !(MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 || MC_VER == MC_1_20_4 || MC_VER == MC_1_20_6) // These versions either don't have BCLib, or the implementation is different
|
// only some MC versions have BCLib and require this fix
|
||||||
|
#if (MC_VER > MC_1_17_1 && MC_VER < MC_1_20_4)
|
||||||
|
|
||||||
// Change the value of CUSTOM_FOG_RENDERING in the bclib client config
|
// Change the value of CUSTOM_FOG_RENDERING in the bclib client config
|
||||||
// This disabled fog from rendering within bclib
|
// This disabled fog from rendering within bclib
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"suggests": {
|
"suggests": {
|
||||||
"blendium": "*"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"breaks": $fabric_incompatibility_list,
|
"breaks": $fabric_incompatibility_list,
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
public void clientLevelUnloadEvent(WorldEvent.Unload event)
|
public void clientLevelUnloadEvent(WorldEvent.Unload event)
|
||||||
#else
|
#else
|
||||||
public void clientLevelUnloadEvent(LevelEvent.Load event)
|
public void clientLevelUnloadEvent(LevelEvent.Unload event)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
LOGGER.info("level unload");
|
LOGGER.info("level unload");
|
||||||
|
|||||||
+14
-2
@@ -73,11 +73,23 @@ public class MixinMinecraft
|
|||||||
&& SelfUpdater.onStart()
|
&& SelfUpdater.onStart()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
runnable = () -> {
|
runnable = () ->
|
||||||
|
{
|
||||||
|
String versionId;
|
||||||
|
EDhApiUpdateBranch updateBranch = EDhApiUpdateBranch.convertAutoToStableOrNightly(Config.Client.Advanced.AutoUpdater.updateBranch.get());
|
||||||
|
if (updateBranch == EDhApiUpdateBranch.STABLE)
|
||||||
|
{
|
||||||
|
versionId = ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
versionId = GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha");
|
||||||
|
}
|
||||||
|
|
||||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||||
// TODO: Change to runnable, instead of tittle screen
|
// TODO: Change to runnable, instead of tittle screen
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()) : GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
versionId
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -5,8 +5,8 @@ org.gradle.caching=true
|
|||||||
|
|
||||||
# Mod Info
|
# Mod Info
|
||||||
mod_name=DistantHorizons
|
mod_name=DistantHorizons
|
||||||
mod_version=2.1.0-a
|
mod_version=2.1.2-a
|
||||||
api_version=2.0.0
|
api_version=2.1.0
|
||||||
maven_group=com.seibel.distanthorizons
|
maven_group=com.seibel.distanthorizons
|
||||||
mod_readable_name=Distant Horizons
|
mod_readable_name=Distant Horizons
|
||||||
mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow.
|
mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow.
|
||||||
@@ -49,7 +49,7 @@ versionStr=
|
|||||||
|
|
||||||
# This defines what MC version Intellij will use for the preprocessor
|
# This defines what MC version Intellij will use for the preprocessor
|
||||||
# and what version is used automatically by build and run commands
|
# and what version is used automatically by build and run commands
|
||||||
mcVer=1.20.6
|
mcVer=1.21
|
||||||
|
|
||||||
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
|
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
|
||||||
#minecraftMemoryJavaArg="-Xmx4G"
|
#minecraftMemoryJavaArg="-Xmx4G"
|
||||||
|
|||||||
+16
-42
@@ -11,41 +11,17 @@ architectury {
|
|||||||
neoForge()
|
neoForge()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this is already defined in the main settings.gradle file, why doesn't it work unless also defined here? (If compiling does work without this block feel free to remove)
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
name "Neoforge"
|
|
||||||
url "https://maven.neoforged.net/releases/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//loom {
|
|
||||||
// forge {
|
|
||||||
// convertAccessWideners.set(true)
|
|
||||||
// extraAccessWideners.add("lod.accesswidener")
|
|
||||||
// mixinConfigs("DistantHorizons.mixins.json")
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
silentMojangMappingsLicense() // Shut the licencing warning
|
silentMojangMappingsLicense() // Shut the licencing warning
|
||||||
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
|
||||||
|
|
||||||
neoForge {
|
neoForge {
|
||||||
// Access wideners are now defined in the `remapJar.atAccessWideners`
|
// Access wideners are defined in the `remapJar.atAccessWideners`
|
||||||
// convertAccessWideners = true
|
|
||||||
// extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
|
|
||||||
|
|
||||||
// Mixins are now defined in the `mods.toml`
|
// Mixins are defined in the `mods.toml`
|
||||||
// mixinConfigs = [
|
|
||||||
// "DistantHorizons.mixins.json"
|
|
||||||
// ]
|
|
||||||
}
|
}
|
||||||
mixin {
|
mixin {
|
||||||
// Mixins are now defined in the `mods.toml`
|
// Mixins are defined in the `mods.toml`
|
||||||
// mixinConfigs = [
|
|
||||||
// "DistantHorizons.mixins.json"
|
|
||||||
// ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// "runs" isn't required, but when we do need it then it can be useful
|
// "runs" isn't required, but when we do need it then it can be useful
|
||||||
@@ -55,7 +31,7 @@ loom {
|
|||||||
setConfigName("NeoForge Client")
|
setConfigName("NeoForge Client")
|
||||||
ideConfigGenerated(true)
|
ideConfigGenerated(true)
|
||||||
runDir("../run")
|
runDir("../run")
|
||||||
// vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
|
//vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
|
||||||
}
|
}
|
||||||
server {
|
server {
|
||||||
server()
|
server()
|
||||||
@@ -66,13 +42,7 @@ loom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
|
||||||
inputFile = shadowJar.archiveFile
|
|
||||||
dependsOn shadowJar
|
|
||||||
// classifier null
|
|
||||||
|
|
||||||
atAccessWideners.add("distanthorizons.accesswidener")
|
|
||||||
}
|
|
||||||
|
|
||||||
def addMod(path, enabled) {
|
def addMod(path, enabled) {
|
||||||
if (enabled == "2")
|
if (enabled == "2")
|
||||||
@@ -80,21 +50,24 @@ def addMod(path, enabled) {
|
|||||||
else if (enabled == "1")
|
else if (enabled == "1")
|
||||||
dependencies { modCompileOnly(path) }
|
dependencies { modCompileOnly(path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||||
mappings loom.layered() {
|
mappings loom.layered()
|
||||||
|
{
|
||||||
// Mojmap mappings
|
// Mojmap mappings
|
||||||
officialMojangMappings()
|
officialMojangMappings()
|
||||||
// Parchment mappings (it adds parameter mappings & javadoc)
|
// Parchment mappings (it adds parameter mappings & javadoc)
|
||||||
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
|
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Neoforge
|
// Neoforge
|
||||||
neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}"
|
neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}"
|
||||||
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
task deleteResources(type: Delete) {
|
task deleteResources(type: Delete) {
|
||||||
delete file("build/resources/main")
|
delete file("build/resources/main")
|
||||||
}
|
}
|
||||||
@@ -113,14 +86,15 @@ tasks.named('runClient') {
|
|||||||
finalizedBy(deleteResources)
|
finalizedBy(deleteResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remapJar {
|
||||||
|
inputFile = shadowJar.archiveFile
|
||||||
|
dependsOn shadowJar
|
||||||
|
|
||||||
|
atAccessWideners.add("distanthorizons.accesswidener")
|
||||||
|
}
|
||||||
|
|
||||||
sourcesJar {
|
sourcesJar {
|
||||||
def commonSources = project(":common").sourcesJar
|
def commonSources = project(":common").sourcesJar
|
||||||
dependsOn commonSources
|
dependsOn commonSources
|
||||||
from commonSources.archiveFile.map { zipTree(it) }
|
from commonSources.archiveFile.map { zipTree(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
//components.java {
|
|
||||||
// withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
|
|
||||||
// skip()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
|
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
|
||||||
}
|
}
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void clientLevelUnloadEvent(LevelEvent.Load event)
|
public void clientLevelUnloadEvent(LevelEvent.Unload event)
|
||||||
{
|
{
|
||||||
LOGGER.info("level unload");
|
LOGGER.info("level unload");
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -98,7 +98,6 @@ public class MixinLevelRenderer
|
|||||||
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
|
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f projectionMatrix, Matrix4f frustumMatrix, CallbackInfo callback)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// get MC's model view and projection matrices
|
|
||||||
#if MC_VER == MC_1_16_5
|
#if MC_VER == MC_1_16_5
|
||||||
// get the matrices from the OpenGL fixed pipeline
|
// get the matrices from the OpenGL fixed pipeline
|
||||||
float[] mcProjMatrixRaw = new float[16];
|
float[] mcProjMatrixRaw = new float[16];
|
||||||
@@ -120,15 +119,21 @@ public class MixinLevelRenderer
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
float frameTime;
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
frameTime = Minecraft.getInstance().getFrameTime();
|
||||||
|
#else
|
||||||
|
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
|
||||||
|
#endif
|
||||||
|
|
||||||
// only render before solid blocks
|
// only render before solid blocks
|
||||||
if (renderType.equals(RenderType.solid()))
|
if (renderType.equals(RenderType.solid()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, Minecraft.getInstance().getFrameTime());
|
ClientApi.INSTANCE.renderLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime);
|
||||||
}
|
}
|
||||||
else if (renderType.equals(RenderType.translucent()))
|
else if (renderType.equals(RenderType.translucent()))
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, Minecraft.getInstance().getFrameTime());
|
ClientApi.INSTANCE.renderDeferredLods(ClientLevelWrapper.getWrapper(this.level), mcModelViewMatrix, mcProjectionMatrix, frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||||
@@ -154,4 +159,5 @@ public class MixinLevelRenderer
|
|||||||
ChunkWrapper.syncedUpdateClientLightStatus();
|
ChunkWrapper.syncedUpdateClientLightStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-2
@@ -8,6 +8,7 @@ import com.seibel.distanthorizons.core.jar.installer.GitlabGetter;
|
|||||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||||
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -75,11 +76,23 @@ public class MixinMinecraft
|
|||||||
&& SelfUpdater.onStart()
|
&& SelfUpdater.onStart()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
runnable = () -> {
|
runnable = () ->
|
||||||
|
{
|
||||||
|
String versionId;
|
||||||
|
EDhApiUpdateBranch updateBranch = EDhApiUpdateBranch.convertAutoToStableOrNightly(Config.Client.Advanced.AutoUpdater.updateBranch.get());
|
||||||
|
if (updateBranch == EDhApiUpdateBranch.STABLE)
|
||||||
|
{
|
||||||
|
versionId = ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
versionId = GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha");
|
||||||
|
}
|
||||||
|
|
||||||
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
Minecraft.getInstance().setScreen(new UpdateModScreen(
|
||||||
// TODO: Change to runnable, instead of tittle screen
|
// TODO: Change to runnable, instead of tittle screen
|
||||||
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
new TitleScreen(false), // We don't want to use the vanilla title screen as it would fade the buttons
|
||||||
(Config.Client.Advanced.AutoUpdater.updateBranch.get() == EDhApiUpdateBranch.STABLE ? ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion()) : GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"))
|
versionId
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-7
@@ -23,16 +23,13 @@ import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import net.minecraft.client.gui.screens.OptionsScreen;
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
#if MC_VER < MC_1_19_2
|
#if MC_VER < MC_1_19_2
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
#endif
|
#endif
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
@@ -41,11 +38,20 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
#if MC_VER == MC_1_20_6
|
#if MC_VER >= MC_1_20_6
|
||||||
import net.minecraft.client.gui.layouts.LinearLayout;
|
import net.minecraft.client.gui.layouts.LinearLayout;
|
||||||
import net.minecraft.client.gui.layouts.HeaderAndFooterLayout;
|
import net.minecraft.client.gui.layouts.HeaderAndFooterLayout;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
import net.minecraft.client.gui.screens.OptionsScreen;
|
||||||
|
#else
|
||||||
|
import net.minecraft.client.gui.screens.options.OptionsScreen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a button to the menu to goto the config
|
* Adds a button to the menu to goto the config
|
||||||
*
|
*
|
||||||
@@ -57,13 +63,18 @@ public class MixinOptionsScreen extends Screen
|
|||||||
{
|
{
|
||||||
/** Texture used for the config opening button */
|
/** Texture used for the config opening button */
|
||||||
@Unique
|
@Unique
|
||||||
private static final ResourceLocation ICON_TEXTURE = new ResourceLocation(ModInfo.ID, "textures/gui/button.png");
|
private static final ResourceLocation ICON_TEXTURE =
|
||||||
|
#if MC_VER < MC_1_21
|
||||||
|
new ResourceLocation(ModInfo.ID, "textures/gui/button.png");
|
||||||
|
#else
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/button.png");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private TexturedButtonWidget optionsButton = null;
|
private TexturedButtonWidget optionsButton = null;
|
||||||
|
|
||||||
#if MC_VER == MC_1_20_6
|
#if MC_VER >= MC_1_20_6
|
||||||
@Shadow
|
@Shadow
|
||||||
@Final
|
@Final
|
||||||
protected HeaderAndFooterLayout layout;
|
protected HeaderAndFooterLayout layout;
|
||||||
@@ -93,7 +104,6 @@ public class MixinOptionsScreen extends Screen
|
|||||||
|
|
||||||
// add the button to the correct location in the UI
|
// add the button to the correct location in the UI
|
||||||
// TODO is there a better way to do this instead of using access transformers to inject into the exact UI elements?
|
// TODO is there a better way to do this instead of using access transformers to inject into the exact UI elements?
|
||||||
// TODO is there a way we can put the button on the left side of the FOV bar like before?
|
|
||||||
LinearLayout layout = (LinearLayout) this.layout.headerFrame.children.get(0).child;
|
LinearLayout layout = (LinearLayout) this.layout.headerFrame.children.get(0).child;
|
||||||
|
|
||||||
// determine how wide the other option buttons are so we can put our botton to the left of them all
|
// determine how wide the other option buttons are so we can put our botton to the left of them all
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# 1.21 version
|
||||||
|
java_version=21
|
||||||
|
minecraft_version=1.21
|
||||||
|
parchment_version=1.20.6:2024.05.01
|
||||||
|
compatible_minecraft_versions=["1.21.0"]
|
||||||
|
accessWidenerVersion=1_20_6
|
||||||
|
builds_for=fabric,neoforge
|
||||||
|
# forge is broken due to gradle/build script issues
|
||||||
|
|
||||||
|
# Fabric loader
|
||||||
|
fabric_loader_version=0.15.11
|
||||||
|
fabric_api_version=0.100.1+1.21
|
||||||
|
# Fabric mod versions
|
||||||
|
modmenu_version=11.0.0-beta.1
|
||||||
|
starlight_version_fabric=
|
||||||
|
phosphor_version_fabric=
|
||||||
|
lithium_version=
|
||||||
|
sodium_version=mc1.21-0.5.9
|
||||||
|
iris_version=1.7.1+1.21
|
||||||
|
bclib_version=
|
||||||
|
immersive_portals_version=
|
||||||
|
canvas_version=
|
||||||
|
|
||||||
|
fabric_incompatibility_list={ "iris": "<=1.6.20" }
|
||||||
|
fabric_recommend_list={}
|
||||||
|
|
||||||
|
# Fabric mod run
|
||||||
|
# 0 = Don't enable and don't run
|
||||||
|
# 1 = Can be referenced in code but doesn't run
|
||||||
|
# 2 = Can be referenced in code and runs in client
|
||||||
|
enable_starlight=0
|
||||||
|
enable_phosphor=0
|
||||||
|
enable_sodium=1
|
||||||
|
enable_lithium=0
|
||||||
|
enable_iris=1
|
||||||
|
enable_bclib=0
|
||||||
|
enable_immersive_portals=0
|
||||||
|
enable_canvas=0
|
||||||
|
|
||||||
|
# (Neo)Forge loader
|
||||||
|
forge_version=50.0.19
|
||||||
|
neoforge_version=21.0.4-beta
|
||||||
|
# (Neo)Forge mod versions
|
||||||
|
starlight_version_forge=
|
||||||
|
terraforged_version=
|
||||||
|
|
||||||
|
# (Neo)Forge mod run
|
||||||
|
# 0 = Don't enable and don't run
|
||||||
|
# 1 = Can be referenced in code but doesn't run
|
||||||
|
# 2 = Can be referenced in code and runs in client
|
||||||
|
enable_starlight_forge=0
|
||||||
|
enable_terraforged=0
|
||||||
|
enable_terrafirmacraft=0
|
||||||
Reference in New Issue
Block a user