diff --git a/Common/build.gradle b/Common/build.gradle index 2dbec7b..e505bfe 100644 --- a/Common/build.gradle +++ b/Common/build.gradle @@ -3,12 +3,19 @@ plugins { id 'org.spongepowered.gradle.vanilla' version '0.2.1-SNAPSHOT' } +repositories { + maven { + url = 'https://alcatrazescapee.jfrog.io/artifactory/mods' + } +} + minecraft { version(minecraft_version) } dependencies { compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5' + compileOnly group: 'com.alcatrazescapee', name: 'epsilon', version: epsilon_version } processResources { diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/PrimalWinter.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/PrimalWinter.java index c777a35..58b10b8 100644 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/PrimalWinter.java +++ b/Common/src/main/java/com/alcatrazescapee/primalwinter/PrimalWinter.java @@ -17,8 +17,6 @@ public static void earlySetup() { LOGGER.info("Early XPlatform Setup"); - Config.INSTANCE.earlySetup(); - PrimalWinterBlocks.BLOCKS.earlySetup(); PrimalWinterBlocks.ITEMS.earlySetup(); PrimalWinterWorldGen.Features.FEATURES.earlySetup(); @@ -41,5 +39,7 @@ public static void lateSetup() PrimalWinterAmbience.SOUND_EVENTS.lateSetup(); PrimalWinterBlocks.registerAxeStrippables(); + + Config.INSTANCE.load(); } } \ No newline at end of file diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/client/ClientEventHandler.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/client/ClientEventHandler.java index df075b7..9870edb 100644 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/client/ClientEventHandler.java +++ b/Common/src/main/java/com/alcatrazescapee/primalwinter/client/ClientEventHandler.java @@ -74,8 +74,8 @@ public static void renderFogColors(Camera camera, float partialTick, FogColorCal final float height = Mth.cos(angle); final float delta = Mth.clamp((height + 0.4f) / 0.8f, 0, 1); - final int colorDay = Config.INSTANCE.fogColorDay.get(); - final int colorNight = Config.INSTANCE.fogColorNight.get(); + final int colorDay = Config.INSTANCE.fogColorDay.getAsInt(); + final int colorNight = Config.INSTANCE.fogColorNight.getAsInt(); final float red = ((colorDay >> 16) & 0xFF) * delta + ((colorNight >> 16) & 0xFF) * (1 - delta); final float green = ((colorDay >> 8) & 0xFF) * delta + ((colorNight >> 8) & 0xFF) * (1 - delta); final float blue = (colorDay & 0xFF) * delta + (colorNight & 0xFF) * (1 - delta); @@ -123,7 +123,7 @@ else if (expectedFogDensity < prevFogDensity) if (prevFogDensity > 0) { final float scaledDelta = 1 - (1 - prevFogDensity) * (1 - prevFogDensity); - final float fogDensity = Config.INSTANCE.fogDensity.get().floatValue(); + final float fogDensity = Config.INSTANCE.fogDensity.getAsFloat(); final float farPlaneScale = Mth.lerp(scaledDelta, 1f, fogDensity); final float nearPlaneScale = Mth.lerp(scaledDelta, 1f, 0.3f * fogDensity); callback.accept(nearPlaneScale, farPlaneScale); diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/mixin/client/DimensionSpecialEffectsMixin.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/mixin/client/DimensionSpecialEffectsMixin.java index 5b40158..edee068 100644 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/mixin/client/DimensionSpecialEffectsMixin.java +++ b/Common/src/main/java/com/alcatrazescapee/primalwinter/mixin/client/DimensionSpecialEffectsMixin.java @@ -22,7 +22,7 @@ private void noSunriseColor(float skyAngle, float tickDelta, CallbackInfoReturna { final float[] original = cir.getReturnValue(); final Level level = Minecraft.getInstance().level; - if (original != null && Config.INSTANCE.weatherRenderChanges.get() && level != null) + if (original != null && Config.INSTANCE.skyRenderChanges.getAsBoolean() && level != null) { final BlockPos pos = Minecraft.getInstance().gameRenderer.getMainCamera().getBlockPosition(); final Holder biome = level.getBiome(pos); diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/mixin/client/LevelRendererMixin.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/mixin/client/LevelRendererMixin.java index f0c36b5..ed13c18 100644 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/mixin/client/LevelRendererMixin.java +++ b/Common/src/main/java/com/alcatrazescapee/primalwinter/mixin/client/LevelRendererMixin.java @@ -33,7 +33,9 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyConstant; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -55,7 +57,7 @@ public abstract class LevelRendererMixin @Redirect(method = "renderSnowAndRain", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/biome/Biome;warmEnoughToRain(Lnet/minecraft/core/BlockPos;)Z")) private boolean alwaysUseRainRendering(Biome biome, BlockPos pos) { - if (Config.INSTANCE.weatherRenderChanges.get()) + if (Config.INSTANCE.weatherRenderChanges.getAsBoolean()) { return true; } @@ -66,7 +68,7 @@ private boolean alwaysUseRainRendering(Biome biome, BlockPos pos) private int getAdjustedLightColorForSnow(BlockAndTintGetter level, BlockPos pos) { final int packedLight = LevelRenderer.getLightColor(level, pos); - if (Config.INSTANCE.weatherRenderChanges.get()) + if (Config.INSTANCE.weatherRenderChanges.getAsBoolean()) { // Adjusts the light color via a heuristic that mojang uses to make snow appear more white // This targets both paths, but since we always use the rain rendering, it's fine. @@ -82,15 +84,28 @@ private int getAdjustedLightColorForSnow(BlockAndTintGetter level, BlockPos pos) @Inject(method = "renderSnowAndRain", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/BufferBuilder;begin(Lcom/mojang/blaze3d/vertex/VertexFormat$Mode;Lcom/mojang/blaze3d/vertex/VertexFormat;)V")) private void overrideWithSnowTextures(LightTexture lightTexture, float partialTick, double x, double y, double z, CallbackInfo ci) { - if (Config.INSTANCE.weatherRenderChanges.get()) + if (Config.INSTANCE.weatherRenderChanges.getAsBoolean()) { RenderSystem.setShaderTexture(0, SNOW_LOCATION); } } + @ModifyConstant(method = "renderSnowAndRain", constant = {@Constant(intValue = 5), @Constant(intValue = 10)}) + private int modifySnowAmount(int constant) + { + // This constant is used to control how much snow is rendered - 5 with default, 10 with fancy graphics. By default, we bump this all the way to 15. + return Config.INSTANCE.snowDensity.getAsInt(); + } + @Inject(method = "tickRain", at = @At("HEAD")) private void addExtraSnowParticlesAndSounds(Camera camera, CallbackInfo ci) { + if (!Config.INSTANCE.snowSounds.getAsBoolean()) + { + // Prevent default rain/snow sounds by setting rainSoundTime to -1, which means the if() checking it will never pass + rainSoundTime = -1; + } + final float rain = level.getRainLevel(1f) / (Minecraft.useFancyGraphics() ? 1f : 2f); if (rain > 0f) { @@ -136,7 +151,7 @@ private void addExtraSnowParticlesAndSounds(Camera camera, CallbackInfo ci) } // Added - if (windSoundTime-- < 0 && Config.INSTANCE.windSounds.get()) + if (windSoundTime-- < 0 && Config.INSTANCE.windSounds.getAsBoolean()) { final BlockPos playerPos = camera.getBlockPosition(); final Entity entity = camera.getEntity(); diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/platform/AbstractConfig.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/platform/AbstractConfig.java deleted file mode 100644 index a6af9b6..0000000 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/platform/AbstractConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.alcatrazescapee.primalwinter.platform; - -import java.util.List; -import java.util.function.Supplier; - -public abstract class AbstractConfig -{ - public void earlySetup() {} - - protected abstract BooleanValue build(Type configType, String name, boolean defaultValue, String comment); - protected abstract DoubleValue build(Type configType, String name, double defaultValue, double minValue, double maxValue, String comment); - protected abstract IntValue build(Type configType, String name, int defaultValue, int minValue, int maxValue, String comment); - protected abstract ListValue build(Type configType, String name, List defaultValue, String comment); - - public interface BooleanValue extends Supplier {} - public interface DoubleValue extends Supplier {} - public interface IntValue extends Supplier {} - public interface ListValue extends Supplier> {} - - public enum Type - { - CLIENT, - COMMON - } -} diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/platform/XPlatform.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/platform/XPlatform.java index 34fcc84..f3a8268 100644 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/platform/XPlatform.java +++ b/Common/src/main/java/com/alcatrazescapee/primalwinter/platform/XPlatform.java @@ -1,5 +1,6 @@ package com.alcatrazescapee.primalwinter.platform; +import java.nio.file.Path; import java.util.ServiceLoader; import java.util.function.Supplier; import net.minecraft.core.Registry; @@ -22,9 +23,11 @@ static T find(Class clazz) RegistryInterface registryInterface(Registry registry); - Config createConfig(); - CreativeModeTab creativeTab(ResourceLocation id, Supplier icon); + // Platform APIs + boolean isDedicatedClient(); + + Path configDir(); } diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/util/Config.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/util/Config.java index 4761d19..33312b1 100644 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/util/Config.java +++ b/Common/src/main/java/com/alcatrazescapee/primalwinter/util/Config.java @@ -1,107 +1,180 @@ package com.alcatrazescapee.primalwinter.util; +import java.nio.file.Path; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.Stream; +import com.mojang.logging.LogUtils; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biomes; import org.jetbrains.annotations.Nullable; - -import com.alcatrazescapee.primalwinter.platform.AbstractConfig; +import org.slf4j.Logger; + +import com.alcatrazescapee.epsilon.EpsilonUtil; +import com.alcatrazescapee.epsilon.ParseError; +import com.alcatrazescapee.epsilon.Spec; +import com.alcatrazescapee.epsilon.SpecBuilder; +import com.alcatrazescapee.epsilon.Type; +import com.alcatrazescapee.epsilon.value.BoolValue; +import com.alcatrazescapee.epsilon.value.FloatValue; +import com.alcatrazescapee.epsilon.value.IntValue; +import com.alcatrazescapee.epsilon.value.TypeValue; +import com.alcatrazescapee.primalwinter.PrimalWinter; import com.alcatrazescapee.primalwinter.platform.XPlatform; -public abstract class Config extends AbstractConfig +public enum Config { - public static final Config INSTANCE = XPlatform.INSTANCE.createConfig(); + INSTANCE; + + private static final Logger LOGGER = LogUtils.getLogger(); // Common - public final BooleanValue enableWeatherCommand; + public final BoolValue enableWeatherCommand; - public final BooleanValue enableSnowAccumulationDuringWorldgen; - public final BooleanValue enableSnowAccumulationDuringWeather; + public final BoolValue enableSnowAccumulationDuringWorldgen; + public final BoolValue enableSnowAccumulationDuringWeather; - public final ListValue nonWinterBiomes; - public final ListValue nonWinterDimensions; + public final TypeValue> nonWinterBiomes; + public final TypeValue>> nonWinterDimensions; - public final BooleanValue invertNonWinterBiomes; - public final BooleanValue invertNonWinterDimensions; + public final BoolValue invertNonWinterBiomes; + public final BoolValue invertNonWinterDimensions; // Client - public final DoubleValue fogDensity; - public final DoubleValue snowDensity; - - public final BooleanValue snowSounds; - public final BooleanValue windSounds; + public final FloatValue fogDensity; + public final IntValue snowDensity; + public final BoolValue windSounds; + public final BoolValue snowSounds; public final IntValue fogColorDay; public final IntValue fogColorNight; - public final BooleanValue weatherRenderChanges; - public final BooleanValue skyRenderChanges; + public final BoolValue weatherRenderChanges; + public final BoolValue skyRenderChanges; - protected Config() - { - // Common - enableWeatherCommand = build(Type.COMMON, "enableWeatherCommand", false, "Should the vanilla /weather be disabled? Any changes require a world restart to take effect."); + private final Spec spec; - enableSnowAccumulationDuringWorldgen = build(Type.COMMON, "enableSnowAccumulationDuringWorldgen", false, " If true, snow will be layered higher than one layer during world generation. Note: due to snow layers being > 1 block tall, this tends to prevent most passive (and hostile) mob spawning on the surface, since there are no places to spawn."); - enableSnowAccumulationDuringWeather = build(Type.COMMON, "enableSnowAccumulationDuringWeather", true, " If true, snow will be layered higher than one layer during weather (snow)."); + Config() + { + final SpecBuilder builder = Spec.builder(); - nonWinterBiomes = build(Type.COMMON, "nonWinterBiomes", getDefaultNonWinterBiomes(), "A list of biome IDs that will not be forcibly converted to frozen wastelands. Any changes requires a MC restart to take effect."); - nonWinterDimensions = build(Type.COMMON, "nonWinterDimensions", getDefaultNonWinterDimensions(), "A list of dimension IDs that will not have winter weather effects set."); + builder.push("general"); - invertNonWinterBiomes = build(Type.COMMON, "invertNonWinterBiomes", false, "If true, the 'nonWinterBiomes' config option will be interpreted as a list of winter biomes, and all others will be ignored."); - invertNonWinterDimensions = build(Type.COMMON, "invertNonWinterDimensions", false, "If true, the 'nonWinterDimensions' config option will be interpreted as a list of winter dimensions, and all others will be ignored."); + // Common + enableWeatherCommand = builder + .comment("Should the vanilla /weather be disabled? Any changes require a world restart to take effect.") + .define("enableWeatherCommand", false); + + enableSnowAccumulationDuringWorldgen = builder + .comment( + "If true, snow will be layered higher than one layer during world generation.", + "Note: due to snow layers being > 1 block tall, this tends to prevent most passive (and hostile) mob spawning on the surface, since there are no places to spawn." + ) + .define("enableSnowAccumulationDuringWorldgen", false); + enableSnowAccumulationDuringWeather = builder + .comment("If true, snow will be layered higher than one layer during weather (snow).") + .define("enableSnowAccumulationDuringWeather", true); + + nonWinterBiomes = builder + .comment("A list of biome IDs that will not be forcibly converted to frozen wastelands. Any changes requires a MC restart to take effect.") + .define("nonWinterBiomes", Stream.of( + Biomes.NETHER_WASTES, + Biomes.CRIMSON_FOREST, + Biomes.WARPED_FOREST, + Biomes.BASALT_DELTAS, + Biomes.SOUL_SAND_VALLEY, + Biomes.END_BARRENS, + Biomes.END_HIGHLANDS, + Biomes.END_MIDLANDS, + Biomes.THE_END, + Biomes.THE_VOID + ).map(ResourceKey::location).toList(), Type.STRING_LIST.map( + list -> list.stream().map(name -> ParseError.require(() -> new ResourceLocation(name))).toList(), + list -> list.stream().map(ResourceLocation::toString).toList(), + TypeValue::new + )); + nonWinterDimensions = builder + .comment("A list of dimension IDs that will not have winter weather effects set.") + .define("nonWinterDimensions", List.of( + Level.NETHER, + Level.END + ), Type.STRING_LIST.map( + list -> list.stream().map(name -> ResourceKey.create(Registry.DIMENSION_REGISTRY, ParseError.require(() -> new ResourceLocation(name)))).toList(), + list -> list.stream().map(rl -> rl.location().toString()).toList(), + TypeValue::new + )); + + invertNonWinterBiomes = builder + .comment("If true, the 'nonWinterBiomes' config option will be interpreted as a list of winter biomes, and all others will be ignored.") + .define("invertNonWinterBiomes", false); + invertNonWinterDimensions = builder + .comment("If true, the 'nonWinterDimensions' config option will be interpreted as a list of winter dimensions, and all others will be ignored.") + .define("invertNonWinterDimensions", false); + + builder.swap("client"); // Client - fogDensity = build(Type.CLIENT, "fogDensity", 0.1, 0, 1, "How dense the fog effect during a snowstorm is."); - snowDensity = build(Type.CLIENT, "snowDensity", 15d, 1d, 15d, "How visually dense the snow weather effect is. Normally, vanilla sets this to 5 with fast graphics, and 10 with fancy graphics."); - snowSounds = build(Type.CLIENT, "snowSounds", true, "Enable snow (actually rain) weather sounds."); - windSounds = build(Type.CLIENT, "windSounds", true, "Enable wind / snow storm weather sounds."); - - fogColorDay = build(Type.CLIENT, "fogColorDay", 0xbfbfd8, 0, 0xFFFFFF, "This is the fog color during the day. Default = #BFBFD8"); - fogColorNight = build(Type.CLIENT, "fogColorNight", 0x0c0c19, 0, 0xFFFFFF, "This is the fog color during the night. Default = #0C0C19"); + fogDensity = builder + .comment("How dense the fog effect during a snowstorm is.") + .define("fogDensity", 0.1f, 0f, 1f); + snowDensity = builder + .comment("How visually dense the snow weather effect is. Normally, vanilla sets this to 5 with fast graphics, and 10 with fancy graphics.") + .define("snowDensity", 15, 1, 15); + snowSounds = builder + .comment("Enable snow (actually rain) weather sounds.") + .define("snowSounds", true); + windSounds = builder + .comment("Enable wind / snow storm weather sounds.") + .define("windSounds", true); + + fogColorDay = builder + .comment("This is the fog color during the day. It must be an RGB hex string.") + .define("fogColorDay", 0xbfbfd8, Type.STRING.map( + str -> ParseError.require(() -> Integer.parseInt(str, 16)), + value -> String.format("%06x", value), + IntValue::new + )); + fogColorNight = builder + .comment("This is the fog color during the night. It must be an RGB hex string.") + .define("fogColorNight", 0x0c0c19, Type.STRING.map( + str -> ParseError.require(() -> Integer.parseInt(str, 16)), + value -> String.format("%06x", value), + IntValue::new + )); + + weatherRenderChanges = builder + .comment("Changes the weather renderer to one which renders faster, denser snow.") + .define("weatherRenderChanges", true); + skyRenderChanges = builder + .comment("Changes the sky renderer to one which does not render sunrise or sunset effects during a snowstorm.") + .define("skyRenderChanges", true); + + spec = builder + .pop() + .build(); + } - weatherRenderChanges = build(Type.CLIENT, "weatherRenderChanges", true, "Changes the weather renderer to one which renders faster, denser snow. Note: this requires a world reload to take effect."); - skyRenderChanges = build(Type.CLIENT, "skyRenderChanges", true, "Changes the sky renderer to one which does not render sunrise or sunset effects during a snowstorm. Note: this requires a world reload to take effect."); + public void load() + { + LOGGER.info("Loading Primal Winter Config"); + EpsilonUtil.parse(spec, Path.of(XPlatform.INSTANCE.configDir().toString(), PrimalWinter.MOD_ID + ".toml"), LOGGER::warn); } - public boolean isWinterDimension(ResourceLocation id) + public boolean isWinterDimension(ResourceKey dimension) { - final String name = id.toString(); - final Stream stream = INSTANCE.nonWinterDimensions.get().stream(); - return INSTANCE.invertNonWinterDimensions.get() ? stream.anyMatch(name::equals) : stream.noneMatch(name::equals); + final Stream> stream = INSTANCE.nonWinterDimensions.get().stream(); + return INSTANCE.invertNonWinterDimensions.getAsBoolean() ? stream.anyMatch(dimension::equals) : stream.noneMatch(dimension::equals); } - public boolean isWinterBiome(@Nullable ResourceLocation id) + public boolean isWinterBiome(@Nullable ResourceLocation name) { - if (id != null) + if (name != null) { - final String name = id.toString(); - final Stream stream = INSTANCE.nonWinterBiomes.get().stream(); - return INSTANCE.invertNonWinterBiomes.get() ? stream.anyMatch(name::equals) : stream.noneMatch(name::equals); + final Stream stream = INSTANCE.nonWinterBiomes.get().stream(); + return INSTANCE.invertNonWinterBiomes.getAsBoolean() ? stream.anyMatch(name::equals) : stream.noneMatch(name::equals); } return false; } - - private List getDefaultNonWinterBiomes() - { - return Stream.of( - Biomes.NETHER_WASTES, - Biomes.CRIMSON_FOREST, - Biomes.WARPED_FOREST, - Biomes.BASALT_DELTAS, - Biomes.SOUL_SAND_VALLEY, - Biomes.END_BARRENS, - Biomes.END_HIGHLANDS, - Biomes.END_MIDLANDS, - Biomes.THE_END, - Biomes.THE_VOID - ).map(key -> key.location().toString()).collect(Collectors.toList()); - } - - private List getDefaultNonWinterDimensions() - { - return Stream.of("minecraft:the_nether", "minecraft:the_end").collect(Collectors.toList()); - } } diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/util/EventHandler.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/util/EventHandler.java index 4c81eee..dd974d6 100644 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/util/EventHandler.java +++ b/Common/src/main/java/com/alcatrazescapee/primalwinter/util/EventHandler.java @@ -1,5 +1,6 @@ package com.alcatrazescapee.primalwinter.util; +import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; import com.mojang.logging.LogUtils; import net.minecraft.commands.CommandSourceStack; @@ -28,7 +29,7 @@ public final class EventHandler public static void registerCommands(CommandDispatcher dispatcher) { - final boolean enable = Config.INSTANCE.enableWeatherCommand.get(); + final boolean enable = Config.INSTANCE.enableWeatherCommand.getAsBoolean(); LOGGER.info("Vanilla /weather enabled = {}", enable); if (!enable) { @@ -39,6 +40,11 @@ public static void registerCommands(CommandDispatcher dispat return 0; })); } + + dispatcher.register(Commands.literal("primalwinterReloadConfig").requires(c -> c.hasPermission(2)).executes(source -> { + Config.INSTANCE.load(); + return Command.SINGLE_SUCCESS; + })); } /** @@ -46,7 +52,7 @@ public static void registerCommands(CommandDispatcher dispat */ public static void placeExtraSnow(ServerLevel level, ChunkAccess chunk) { - if (Config.INSTANCE.enableSnowAccumulationDuringWeather.get() && level.random.nextInt(16) == 0) + if (Config.INSTANCE.enableSnowAccumulationDuringWeather.getAsBoolean() && level.random.nextInt(16) == 0) { final int blockX = chunk.getPos().getMinBlockX(); final int blockZ = chunk.getPos().getMinBlockZ(); @@ -78,7 +84,7 @@ public static void placeExtraSnow(ServerLevel level, ChunkAccess chunk) public static void setLevelToThunder(LevelAccessor maybeLevel) { - if (maybeLevel instanceof ServerLevel level && Config.INSTANCE.isWinterDimension(level.dimension().location())) + if (maybeLevel instanceof ServerLevel level && Config.INSTANCE.isWinterDimension(level.dimension())) { NewWorldSavedData.onlyForNewWorlds(level, () -> { LOGGER.info("Modifying weather for world {}", level.dimension().location()); diff --git a/Common/src/main/java/com/alcatrazescapee/primalwinter/world/ImprovedFreezeTopLayerFeature.java b/Common/src/main/java/com/alcatrazescapee/primalwinter/world/ImprovedFreezeTopLayerFeature.java index 68cc28e..de09eef 100644 --- a/Common/src/main/java/com/alcatrazescapee/primalwinter/world/ImprovedFreezeTopLayerFeature.java +++ b/Common/src/main/java/com/alcatrazescapee/primalwinter/world/ImprovedFreezeTopLayerFeature.java @@ -184,7 +184,7 @@ else if (Blocks.SNOW.defaultBlockState().canSurvive(level, pos) && state.getMate } int layers; - if (Config.INSTANCE.enableSnowAccumulationDuringWorldgen.get()) + if (Config.INSTANCE.enableSnowAccumulationDuringWorldgen.getAsBoolean()) { layers = Mth.clamp(skyLight - random.nextInt(3) - countExposedFaces(level, pos), 1, 7); } diff --git a/Data/main.py b/Data/main.py index 86ee54a..1b878d8 100644 --- a/Data/main.py +++ b/Data/main.py @@ -141,7 +141,7 @@ def main(): common.flush() -def vine_element(texture: str, tint: int) -> JsonObject: +def vine_element(texture: str, tint: int | None) -> JsonObject: return { 'from': [0, 0, 0.8], 'to': [16, 16, 0.8], diff --git a/Fabric/build.gradle b/Fabric/build.gradle index 6e808c6..b212d65 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -2,12 +2,24 @@ plugins { id 'fabric-loom' version '0.12-SNAPSHOT' id 'io.github.juuxel.loom-quiltflower' version '1.7.2' id 'idea' + id 'com.github.johnrengelman.shadow' version '7.1.2' } def envVersion = System.getenv('VERSION') version = envVersion == null ? '0.0.0-indev' : envVersion archivesBaseName = "${mod_id}-fabric-${minecraft_version}" +configurations { + shadowLibrary + implementation.extendsFrom(shadowLibrary) +} + +repositories { + maven { + url = 'https://alcatrazescapee.jfrog.io/artifactory/mods' + } +} + dependencies { minecraft "com.mojang:minecraft:${minecraft_version}" mappings loom.layered() { @@ -18,8 +30,7 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" - modImplementation "me.zeroeightsix:fiber:0.23.0-2" - include "me.zeroeightsix:fiber:0.23.0-2" + shadowLibrary "com.alcatrazescapee:epsilon:${epsilon_version}" implementation project(":Common") implementation 'org.jetbrains:annotations:23.0.0' @@ -57,8 +68,22 @@ tasks.withType(JavaCompile) { } jar { + classifier 'slim' from("LICENSE") { rename { "${it}_${mod_name}" } } } +shadowJar { + from sourceSets.main.output + configurations = [project.configurations.shadowLibrary] + dependencies { + exclude(dependency { it.moduleGroup != 'com.alcatrazescapee' }) + } + relocate 'com.alcatrazescapee.epsilon', 'com.alcatrazescapee.notreepunching.epsilon' +} + +remapJar { + dependsOn shadowJar + inputFile.set(shadowJar.archiveFile) +} diff --git a/Fabric/src/main/java/com/alcatrazescapee/primalwinter/platform/FabricConfig.java b/Fabric/src/main/java/com/alcatrazescapee/primalwinter/platform/FabricConfig.java deleted file mode 100644 index b06c073..0000000 --- a/Fabric/src/main/java/com/alcatrazescapee/primalwinter/platform/FabricConfig.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.alcatrazescapee.primalwinter.platform; - -import java.io.*; -import java.nio.file.*; -import java.util.List; -import java.util.function.Function; -import java.util.function.Supplier; - -import com.alcatrazescapee.primalwinter.PrimalWinter; -import com.alcatrazescapee.primalwinter.util.Config; -import com.mojang.logging.LogUtils; -import io.github.fablabsmc.fablabs.api.fiber.v1.builder.ConfigLeafBuilder; -import io.github.fablabsmc.fablabs.api.fiber.v1.builder.ConfigTreeBuilder; -import io.github.fablabsmc.fablabs.api.fiber.v1.exception.ValueDeserializationException; -import io.github.fablabsmc.fablabs.api.fiber.v1.schema.type.derived.ConfigType; -import io.github.fablabsmc.fablabs.api.fiber.v1.schema.type.derived.ConfigTypes; -import io.github.fablabsmc.fablabs.api.fiber.v1.schema.type.derived.ListConfigType; -import io.github.fablabsmc.fablabs.api.fiber.v1.serialization.FiberSerialization; -import io.github.fablabsmc.fablabs.api.fiber.v1.serialization.JanksonValueSerializer; -import io.github.fablabsmc.fablabs.api.fiber.v1.tree.ConfigTree; -import io.github.fablabsmc.fablabs.api.fiber.v1.tree.PropertyMirror; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; - -import static io.github.fablabsmc.fablabs.api.fiber.v1.schema.type.derived.ConfigTypes.*; - -public final class FabricConfig -{ - private static final Logger LOGGER = LogUtils.getLogger(); - - private static final ListConfigType, String> STRING_LIST = makeList(STRING); - - public static Config create() - { - try - { - Files.createDirectory(Paths.get("config")); - } - catch (FileAlreadyExistsException ignored) {} - catch (IOException e) - { - LOGGER.warn("Failed to make config directory", e); - } - - final JanksonValueSerializer serializer = new JanksonValueSerializer(false); - final boolean dedicatedClient = XPlatform.INSTANCE.isDedicatedClient(); - final ConfigTreeBuilder common = ConfigTree.builder(); - final @Nullable ConfigTreeBuilder client = dedicatedClient ? ConfigTree.builder() : null; - - final Config config = new Config() - { - - @Override - protected BooleanValue build(Type configType, String name, boolean defaultValue, String comment) - { - return builder(configType, name, b -> b.beginValue(name, BOOLEAN, defaultValue).withComment(comment), BOOLEAN)::get; - } - - @Override - protected DoubleValue build(Type configType, String name, double defaultValue, double minValue, double maxValue, String comment) - { - return builder(configType, name, b -> b.beginValue(name, DOUBLE.withMinimum(minValue).withMaximum(maxValue), defaultValue), DOUBLE)::get; - } - - @Override - protected IntValue build(Type configType, String name, int defaultValue, int minValue, int maxValue, String comment) - { - return builder(configType, name, b -> b.beginValue(name, INTEGER.withMinimum(minValue).withMaximum(maxValue), defaultValue).withComment(comment), INTEGER)::get; - } - - @Override - protected ListValue build(Type configType, String name, List defaultValue, String comment) - { - return builder(configType, name, b -> b.beginValue(name, STRING_LIST, defaultValue).withComment(comment), STRING_LIST)::get; - } - - private Supplier builder(Type configType, String name, Function> factory, ConfigType converter) - { - final @Nullable ConfigTreeBuilder builder = configType == Type.COMMON ? common : client; - if (builder != null) - { - final PropertyMirror mirror = PropertyMirror.create(converter); - factory.apply(builder).finishValue(mirror::mirror); - return mirror::getValue; - } - return () -> { - throw new IllegalStateException("Tried to access client config option: " + name + " on common side"); - }; - } - }; - - setupConfig(common, Paths.get("config", PrimalWinter.MOD_ID + "-common.json5"), serializer); - if (dedicatedClient) - { - setupConfig(client, Paths.get("config", PrimalWinter.MOD_ID + "-client.json5"), serializer); - } - - return config; - } - - private static void setupConfig(ConfigTree config, Path p, JanksonValueSerializer serializer) - { - writeDefaultConfig(config, p, serializer); - try (InputStream s = new BufferedInputStream(Files.newInputStream(p, StandardOpenOption.READ, StandardOpenOption.CREATE))) - { - FiberSerialization.deserialize(config, s, serializer); - } - catch (IOException | ValueDeserializationException e) - { - LOGGER.error("Error loading config from {}: {}", p, e); - } - } - - private static void writeDefaultConfig(ConfigTree config, Path path, JanksonValueSerializer serializer) - { - try (OutputStream s = new BufferedOutputStream(Files.newOutputStream(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW))) - { - FiberSerialization.serialize(config, s, serializer); - } - catch (FileAlreadyExistsException ignored) {} - catch (IOException e) - { - LOGGER.error("Error writing default config", e); - } - } -} diff --git a/Fabric/src/main/java/com/alcatrazescapee/primalwinter/platform/FabricPlatform.java b/Fabric/src/main/java/com/alcatrazescapee/primalwinter/platform/FabricPlatform.java index 28bba0b..98d6335 100644 --- a/Fabric/src/main/java/com/alcatrazescapee/primalwinter/platform/FabricPlatform.java +++ b/Fabric/src/main/java/com/alcatrazescapee/primalwinter/platform/FabricPlatform.java @@ -1,5 +1,6 @@ package com.alcatrazescapee.primalwinter.platform; +import java.nio.file.Path; import java.util.function.Supplier; import net.minecraft.core.Registry; @@ -20,12 +21,6 @@ public RegistryInterface registryInterface(Registry registry) return new FabricRegistryInterface<>(registry); } - @Override - public Config createConfig() - { - return FabricConfig.create(); - } - @Override public CreativeModeTab creativeTab(ResourceLocation id, Supplier icon) { @@ -37,4 +32,10 @@ public boolean isDedicatedClient() { return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT; } + + @Override + public Path configDir() + { + return FabricLoader.getInstance().getConfigDir(); + } } diff --git a/Forge/build.gradle b/Forge/build.gradle index 5e22653..b61f93e 100644 --- a/Forge/build.gradle +++ b/Forge/build.gradle @@ -16,6 +16,7 @@ buildscript { plugins { id 'java' id 'idea' + id 'com.github.johnrengelman.shadow' version '7.1.2' } apply plugin: 'net.minecraftforge.gradle' @@ -59,6 +60,17 @@ minecraft { } } +configurations { + shadowLibrary + minecraftLibrary.extendsFrom(shadowLibrary) +} + +repositories { + maven { + url = 'https://alcatrazescapee.jfrog.io/artifactory/mods' + } +} + dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" @@ -67,6 +79,8 @@ dependencies { } compileOnly project(":Common") + + shadowLibrary "com.alcatrazescapee:epsilon:${epsilon_version}" } mixin { @@ -85,3 +99,24 @@ processResources { } jar.finalizedBy('reobfJar') + +jar { + classifier 'slim' +} + +shadowJar { + classifier '' + configurations = [project.configurations.shadowLibrary] + dependencies { + exclude(dependency { it.moduleGroup != 'com.alcatrazescapee' }) + } + relocate 'com.alcatrazescapee.epsilon', 'com.alcatrazescapee.notreepunching.epsilon' + finalizedBy 'reobfShadowJar' +} + +assemble.dependsOn(shadowJar) + +reobf { + shadowJar {} +} + diff --git a/Forge/src/main/java/com/alcatrazescapee/primalwinter/platform/ForgeConfig.java b/Forge/src/main/java/com/alcatrazescapee/primalwinter/platform/ForgeConfig.java deleted file mode 100644 index 2f0d6dd..0000000 --- a/Forge/src/main/java/com/alcatrazescapee/primalwinter/platform/ForgeConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.alcatrazescapee.primalwinter.platform; - -import java.util.List; - -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.config.ModConfig; - -import com.alcatrazescapee.primalwinter.util.Config; - -public final class ForgeConfig -{ - public static Config create() - { - final ForgeConfigSpec.Builder common = new ForgeConfigSpec.Builder(); - final ForgeConfigSpec.Builder client = new ForgeConfigSpec.Builder(); - final Config config = new Config() { - - @Override - protected BooleanValue build(Type configType, String name, boolean defaultValue, String comment) - { - return builder(configType, comment).define(name, defaultValue)::get; - } - - @Override - protected DoubleValue build(Type configType, String name, double defaultValue, double minValue, double maxValue, String comment) - { - return builder(configType, comment).defineInRange(name, defaultValue, minValue, maxValue)::get; - } - - @Override - protected IntValue build(Type configType, String name, int defaultValue, int minValue, int maxValue, String comment) - { - return builder(configType, comment).defineInRange(name, defaultValue, minValue, maxValue)::get; - } - - @Override - @SuppressWarnings("unchecked") - protected ListValue build(Type configType, String name, List defaultValue, String comment) - { - final ForgeConfigSpec.ConfigValue> value = builder(configType, comment).defineList(name, defaultValue, e -> e instanceof String); - return () -> (List) value.get(); - } - - private ForgeConfigSpec.Builder builder(Config.Type configType, String comment) - { - return (configType == Type.COMMON ? common : client).comment(" " + comment); - } - }; - - ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, common.build()); - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, client.build()); - return config; - } -} diff --git a/Forge/src/main/java/com/alcatrazescapee/primalwinter/platform/ForgePlatform.java b/Forge/src/main/java/com/alcatrazescapee/primalwinter/platform/ForgePlatform.java index 3363d03..c149d48 100644 --- a/Forge/src/main/java/com/alcatrazescapee/primalwinter/platform/ForgePlatform.java +++ b/Forge/src/main/java/com/alcatrazescapee/primalwinter/platform/ForgePlatform.java @@ -1,5 +1,6 @@ package com.alcatrazescapee.primalwinter.platform; +import java.nio.file.Path; import java.util.function.Supplier; import net.minecraft.core.Registry; @@ -9,6 +10,7 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.loading.FMLEnvironment; import net.minecraftforge.fml.loading.FMLLoader; +import net.minecraftforge.fml.loading.FMLPaths; import com.alcatrazescapee.primalwinter.util.Config; @@ -20,12 +22,6 @@ public RegistryInterface registryInterface(Registry registry) return new ForgeRegistryInterface<>(registry); } - @Override - public Config createConfig() - { - return ForgeConfig.create(); - } - @Override public CreativeModeTab creativeTab(ResourceLocation id, Supplier icon) { @@ -43,4 +39,10 @@ public boolean isDedicatedClient() { return FMLEnvironment.dist == Dist.CLIENT; } + + @Override + public Path configDir() + { + return FMLPaths.CONFIGDIR.get(); + } } diff --git a/gradle.properties b/gradle.properties index e3d2be9..1c9bfcc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,6 +16,9 @@ mod_name=Primal Winter mod_author=AlcatrazEscapee mod_id=primalwinter +# Dependencies +epsilon_version=0.3 + # Gradle org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false \ No newline at end of file