diff --git a/src/main/java/codes/ztereohype/example/config/Config.java b/src/main/java/codes/ztereohype/example/config/Config.java index 930b0b0..1725265 100644 --- a/src/main/java/codes/ztereohype/example/config/Config.java +++ b/src/main/java/codes/ztereohype/example/config/Config.java @@ -1,12 +1,15 @@ package codes.ztereohype.example.config; +import lombok.Data; + +@Data public class Config { - public Config(boolean tweakedLigthmap, boolean twinklingStars, boolean nebulas, String nebulaType, float nebulaStrength) { + public Config(boolean tweakedLigthmap, boolean twinklingStars, boolean nebulas, String nebulaType, float nebulaStrength, float nebulaNoiseAmount, float nebulaNoiseScale, int baseColourAmount) { this.tweakedLigthmap = tweakedLigthmap; this.twinklingStars = twinklingStars; this.nebulas = nebulas; - this.nebulaConfig = new NebulaConfig(nebulaType, nebulaStrength); + this.nebulaConfig = new NebulaConfig(nebulaType, nebulaStrength, nebulaNoiseAmount, nebulaNoiseScale, baseColourAmount); } private boolean tweakedLigthmap; @@ -15,67 +18,20 @@ public class Config { private final NebulaConfig nebulaConfig; - public boolean isTweakedLigthmap() { - return this.tweakedLigthmap; - } - - public boolean isTwinklingStars() { - return this.twinklingStars; - } - - public boolean isNebulas() { - return this.nebulas; - } - - public NebulaConfig getNebulaConfig() { - return this.nebulaConfig; - } - - public void setTweakedLigthmap(boolean tweakedLigthmap) { - this.tweakedLigthmap = tweakedLigthmap; - } - - public void setTwinklingStars(boolean twinklingStars) { - this.twinklingStars = twinklingStars; - } - - public void setNebulas(boolean nebulas) { - this.nebulas = nebulas; - } - + @Data public static final class NebulaConfig { - public NebulaConfig(String nebulaType, float nebulaStrength) { + public NebulaConfig(String nebulaType, float nebulaStrength, float nebulaNoiseAmount, float nebulaNoiseScale, int baseColourAmount) { this.nebulaType = nebulaType; this.nebulaStrength = nebulaStrength; + this.nebulaNoiseAmount = nebulaNoiseAmount; + this.nebulaNoiseScale = nebulaNoiseScale; + this.baseColourAmount = baseColourAmount; } private String nebulaType; private float nebulaStrength; - - public String getNebulaType() { - return this.nebulaType; - } - - public void setNebulaType(String nebulaType) { - this.nebulaType = nebulaType; - } - - public float getNebulaStrength() { - return this.nebulaStrength; - } - - public void setNebulaStrength(float nebulaStrength) { - this.nebulaStrength = nebulaStrength; - } - } - - @Override - public String toString() { - return "Config{" + - "tweakedLigthmap=" + tweakedLigthmap + - ", twinklingStars=" + twinklingStars + - ", nebulas=" + nebulas + - ", nebulaConfig=" + nebulaConfig + - '}'; + private float nebulaNoiseAmount; + private float nebulaNoiseScale; + private int baseColourAmount; } } diff --git a/src/main/java/codes/ztereohype/example/config/ConfigManager.java b/src/main/java/codes/ztereohype/example/config/ConfigManager.java index d8c42e5..1200f2b 100644 --- a/src/main/java/codes/ztereohype/example/config/ConfigManager.java +++ b/src/main/java/codes/ztereohype/example/config/ConfigManager.java @@ -8,6 +8,8 @@ import java.io.FileWriter; import java.io.IOException; public class ConfigManager { + public static final Config DEFAULT_CONFIG = new Config(false, true, true, NebulaType.RAINBOW.getTypeString(), 1f, 0.5f, 1f, 128); + private static final Gson gson = new Gson(); private final Config config; private final File file; @@ -19,7 +21,7 @@ public class ConfigManager { file.getParentFile().mkdirs(); file.createNewFile(); - config = new Config(false, true, true, "rainbow", 1f); + config = cloneConfig(DEFAULT_CONFIG); gson.toJson(config, new FileWriter(file)); } else { @@ -32,7 +34,7 @@ public class ConfigManager { } catch (IOException e) { // todo setup logger properly e.printStackTrace(); - config = new Config(false, true, true, "rainbow", 1f); + config = cloneConfig(DEFAULT_CONFIG); } return new ConfigManager(config, file); @@ -57,13 +59,25 @@ public class ConfigManager { } public NebulaType getNebulaType() { - return NebulaType.getFromString(config.getNebulaConfig().getNebulaType()); + return NebulaType.valueOf(config.getNebulaConfig().getNebulaType().toUpperCase()); } public float getNebulaStrength() { return config.getNebulaConfig().getNebulaStrength(); } + public float getNebulaNoiseAmount() { + return config.getNebulaConfig().getNebulaNoiseAmount(); + } + + public float getNebulaNoiseScale() { + return config.getNebulaConfig().getNebulaNoiseScale(); + } + + public int getNebulaBaseColourAmount() { + return config.getNebulaConfig().getBaseColourAmount(); + } + public void setLightmapTweaked(boolean tweaked) { config.setTweakedLigthmap(tweaked); save(file); @@ -89,6 +103,21 @@ public class ConfigManager { save(file); } + public void setNebulaNoiseAmount(float amount) { + config.getNebulaConfig().setNebulaNoiseAmount(amount); + save(file); + } + + public void setNebulaNoiseScale(float scale) { + config.getNebulaConfig().setNebulaNoiseScale(scale); + save(file); + } + + public void setNebulaBaseColourAmount(int amount) { + config.getNebulaConfig().setBaseColourAmount(amount); + save(file); + } + public void save(File file) { try (FileWriter writer = new FileWriter(file)) { writer.write(gson.toJson(config)); @@ -99,4 +128,21 @@ public class ConfigManager { // LogManager.getLogManager().getLogger("NicerSkies").warning("Failed to save config file!"); } } + + private static Config cloneConfig(Config config) { + return gson.fromJson(gson.toJson(config), Config.class); + } + + public boolean nebulaConfigEquals(Config config) { + return this.config.getNebulaConfig().equals(config.getNebulaConfig()); + } + + public void resetNebulaSettings() { + config.getNebulaConfig().setNebulaType(DEFAULT_CONFIG.getNebulaConfig().getNebulaType()); + config.getNebulaConfig().setNebulaStrength(DEFAULT_CONFIG.getNebulaConfig().getNebulaStrength()); + config.getNebulaConfig().setNebulaNoiseAmount(DEFAULT_CONFIG.getNebulaConfig().getNebulaNoiseAmount()); + config.getNebulaConfig().setNebulaNoiseScale(DEFAULT_CONFIG.getNebulaConfig().getNebulaNoiseScale()); + config.getNebulaConfig().setBaseColourAmount(DEFAULT_CONFIG.getNebulaConfig().getBaseColourAmount()); + save(file); + } } diff --git a/src/main/java/codes/ztereohype/example/core/NebulaSeedManager.java b/src/main/java/codes/ztereohype/example/core/NebulaSeedManager.java index 5a4a175..09d06a5 100644 --- a/src/main/java/codes/ztereohype/example/core/NebulaSeedManager.java +++ b/src/main/java/codes/ztereohype/example/core/NebulaSeedManager.java @@ -14,4 +14,8 @@ public class NebulaSeedManager { return Objects.requireNonNull(Minecraft.getInstance().getCurrentServer()).ip.hashCode(); } } + + public static boolean canGetSeed() { + return Minecraft.getInstance().hasSingleplayerServer() || Minecraft.getInstance().getCurrentServer() != null; + } } diff --git a/src/main/java/codes/ztereohype/example/gui/ConfigScreen.java b/src/main/java/codes/ztereohype/example/gui/ConfigScreen.java index f420402..93d7d23 100644 --- a/src/main/java/codes/ztereohype/example/gui/ConfigScreen.java +++ b/src/main/java/codes/ztereohype/example/gui/ConfigScreen.java @@ -2,7 +2,6 @@ package codes.ztereohype.example.gui; import codes.ztereohype.example.NicerSkies; import codes.ztereohype.example.config.ConfigManager; -import codes.ztereohype.example.config.NebulaType; import codes.ztereohype.example.core.NebulaSeedManager; import codes.ztereohype.example.gui.widget.Separator; import com.mojang.blaze3d.vertex.PoseStack; @@ -10,13 +9,15 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.AbstractSliderButton; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Checkbox; -import net.minecraft.client.gui.components.CycleButton; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.NotNull; public class ConfigScreen extends Screen { - private Screen lastScreen; - private ConfigManager cm = NicerSkies.config; + private final Screen lastScreen; + private final ConfigManager cm = NicerSkies.config; + + private boolean invalidated = false; protected ConfigScreen(Screen lastScreen) { super(Component.literal("Nicer Skies Config")); @@ -33,7 +34,7 @@ public class ConfigScreen extends Screen { } }); - addRenderableWidget(new Checkbox(20, 90, 20, 20, Component.literal("Twinlke Stars"), cm.getTwinklingStars()) { + addRenderableWidget(new Checkbox(20, 84, 20, 20, Component.literal("Twinlke Stars"), cm.getTwinklingStars()) { @Override public void onPress() { super.onPress(); @@ -41,7 +42,7 @@ public class ConfigScreen extends Screen { } }); - addRenderableWidget(new Checkbox(20, 120, 20, 20, Component.literal("Custom Lightmap"), cm.getLightmapTweaked()) { + addRenderableWidget(new Checkbox(20, 108, 20, 20, Component.literal("Custom Lightmap"), cm.getLightmapTweaked()) { @Override public void onPress() { super.onPress(); @@ -52,22 +53,20 @@ public class ConfigScreen extends Screen { addRenderableOnly(new Separator(this.width / 2, 30, this.height - 70)); - { - CycleButton nebulaType = CycleButton.builder((NebulaType value) -> Component.literal(value.getTypeString())) - .withValues(NebulaType.values()) - .withTooltip((type) -> minecraft.font.split(Component.literal("Currently disabled as there's only one type of nebula"), 200)) - .create(this.width / 2 + (this.width / 2 - 150) / 2, 60, 150, 20, Component.literal("Nebula Type"), (button, value) -> { - NicerSkies.config.setNebulaType(value); - }); - - if (NebulaType.values().length < 2) - nebulaType.active = false; // deactivate while theres only one! - - addRenderableWidget(nebulaType); - } +// CycleButton nebulaType = CycleButton.builder((NebulaType value) -> Component.literal(value.getTypeString())) +// .withValues(NebulaType.values()) +// .create(this.width / 2 + (this.width / 2 - 150) / 2, 60, 150, 20, Component.literal("Nebula Type"), (button, value) -> { +// invalidated = true; +// NicerSkies.config.setNebulaType(value); +// }); +// +// if (NebulaType.values().length < 2) +// nebulaType.active = false; // deactivate while theres only one! +// +// addRenderableWidget(nebulaType); float strength = cm.getNebulaStrength(); - addRenderableWidget(new AbstractSliderButton(this.width / 2 + (this.width / 2 - 150) / 2, 90, 150, 20, Component.literal("Nebula Strength: " + (int) (strength * 100) + "%"), strength) { + addRenderableWidget(new AbstractSliderButton(this.width / 2 + (this.width / 2 - 150) / 2, 60, 150, 20, Component.literal("Nebula Strength: " + (int) (strength * 100) + "%"), strength) { @Override protected void updateMessage() { this.setMessage(Component.literal("Nebula Strength: " + (int) (this.value * 100) + "%")); @@ -79,18 +78,87 @@ public class ConfigScreen extends Screen { } }); + float noiseAmount = cm.getNebulaNoiseAmount(); + addRenderableWidget(new AbstractSliderButton(this.width / 2 + (this.width / 2 - 150) / 2, 84, 150, 20, Component.literal("Nebula Amount: " + (int) (noiseAmount * 100) + "%"), noiseAmount) { + @Override + protected void updateMessage() { + invalidated = true; + this.setMessage(Component.literal("Nebula Amount: " + (int) (this.value * 100) + "%")); + } + + @Override + protected void applyValue() { + NicerSkies.config.setNebulaNoiseAmount((float) this.value); + } + }); + + int baseColourAmount = cm.getNebulaBaseColourAmount(); + addRenderableWidget(new AbstractSliderButton(this.width / 2 + (this.width / 2 - 150) / 2, 108, 150, 20, Component.literal("Background Strength: " + baseColourAmount), baseColourAmount / 255f) { + @Override + protected void updateMessage() { + invalidated = true; + this.setMessage(Component.literal("Background Strength: " + (int) (this.value * 255))); + } + + @Override + protected void applyValue() { + NicerSkies.config.setNebulaBaseColourAmount((int) (this.value * 255)); + } + }); + + float nebulaNoiseScale = cm.getNebulaNoiseScale(); + addRenderableWidget(new AbstractSliderButton(this.width / 2 + (this.width / 2 - 150) / 2, 132, 150, 20, Component.literal("Nebula Scale: " + nebulaNoiseScale), Math.round((nebulaNoiseScale - 0.5f) / 1.5f * 100) / 100f) { + @Override + protected void updateMessage() { + invalidated = true; + this.setMessage(Component.literal("Nebula Scale: " + (getNebulaNoiseScale()))); + } + + @Override + protected void applyValue() { + NicerSkies.config.setNebulaNoiseScale(getNebulaNoiseScale()); + } + + private float getNebulaNoiseScale() { + return (float) Math.round((this.value * 1.5f + 0.5f) * 100) / 100f; + } + }); + //reload nebula button - addRenderableWidget(new Button(this.width / 2 + (this.width / 2 - 150) / 2, 120, 150, 20, Component.literal("Reload Sky"), (button) -> { + addRenderableWidget(new Button(this.width / 2 + (this.width / 2 - 150) / 2, 156, 74, 20, Component.literal("Apply"), (button) -> { NicerSkies.skyManager.generateSky(NebulaSeedManager.getSeed()); - })); + invalidated = false; + }) { + @Override + public void render(@NotNull PoseStack poseStack, int mouseX, int mouseY, float partialTick) { + this.active = invalidated && NebulaSeedManager.canGetSeed(); + super.render(poseStack, mouseX, mouseY, partialTick); + } + }); + + //reset to default + addRenderableWidget(new Button(this.width / 2 + (this.width / 2 - 150) / 2 + 76, 156, 74, 20, Component.literal("Reset"), (button) -> { + cm.resetNebulaSettings(); + // find better way to reload screen + this.clearWidgets(); + this.init(); + invalidated = true; + }) { + @Override + public void render(@NotNull PoseStack poseStack, int mouseX, int mouseY, float partialTick) { + this.active = !isDefaultNebulaSettings(); + super.render(poseStack, mouseX, mouseY, partialTick); + } + }); + addRenderableWidget(new Button(this.width / 2 - 100, this.height - 30, 200, 20, Component.literal("Back"), (button) -> { - minecraft.setScreen(lastScreen); + this.onClose(); })); } @Override - public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTick) { + public void render(@NotNull PoseStack poseStack, int mouseX, int mouseY, float partialTick) { this.renderBackground(poseStack); super.render(poseStack, mouseX, mouseY, partialTick); @@ -98,4 +166,16 @@ public class ConfigScreen extends Screen { drawCenteredString(poseStack, this.font, "Toggle Features", this.width / 4, 36, 16777215); drawCenteredString(poseStack, this.font, "Nebula Settings", 3 * this.width / 4, 36, 16777215); } + + @Override + public void onClose() { + if (invalidated) { + NicerSkies.skyManager.generateSky(NebulaSeedManager.getSeed()); + } + minecraft.setScreen(lastScreen); + } + + private boolean isDefaultNebulaSettings() { + return cm.nebulaConfigEquals(ConfigManager.DEFAULT_CONFIG); + } } diff --git a/src/main/java/codes/ztereohype/example/sky/SkyManager.java b/src/main/java/codes/ztereohype/example/sky/SkyManager.java index 3a07987..9933b89 100644 --- a/src/main/java/codes/ztereohype/example/sky/SkyManager.java +++ b/src/main/java/codes/ztereohype/example/sky/SkyManager.java @@ -1,5 +1,7 @@ package codes.ztereohype.example.sky; +import codes.ztereohype.example.NicerSkies; +import codes.ztereohype.example.config.ConfigManager; import codes.ztereohype.example.core.Gradient; import codes.ztereohype.example.sky.nebula.NebulaSkyboxPainter; import codes.ztereohype.example.sky.nebula.Skybox; @@ -21,6 +23,8 @@ public class SkyManager { // private final Gradient starryGradient = new Gradient(); public void generateSky(long seed) { + ConfigManager cm = NicerSkies.config; + nebulaGradient.clear(); starGradient.clear(); @@ -29,7 +33,7 @@ public class SkyManager { RandomSource randomSource = RandomSource.create(seed); //todo: world seed/hash server ip PerlinNoise perlinNoise = PerlinNoise.create(randomSource, IntStream.of(1, 2, 3, 4, 5)); - NebulaSkyboxPainter painter = new NebulaSkyboxPainter(perlinNoise, nebulaGradient); + NebulaSkyboxPainter painter = new NebulaSkyboxPainter(perlinNoise, nebulaGradient, cm.getNebulaNoiseScale(), cm.getNebulaNoiseAmount(), cm.getNebulaBaseColourAmount()); // StarSkyboxPainter painter = new StarSkyboxPainter(perlinNoise, starryGradient); diff --git a/src/main/java/codes/ztereohype/example/sky/nebula/NebulaSkyboxPainter.java b/src/main/java/codes/ztereohype/example/sky/nebula/NebulaSkyboxPainter.java index 286551a..98c00bd 100644 --- a/src/main/java/codes/ztereohype/example/sky/nebula/NebulaSkyboxPainter.java +++ b/src/main/java/codes/ztereohype/example/sky/nebula/NebulaSkyboxPainter.java @@ -6,15 +6,19 @@ import net.minecraft.util.Mth; import net.minecraft.world.level.levelgen.synth.PerlinNoise; public class NebulaSkyboxPainter extends SkyboxPainter { - private static final float SCALING_FACTOR = 1f; - private static final float NOISE_AMOUNT = 0.51f; // the amount of base noise to keep - private static final int BASE_COLOUR_STRENGTH = 128; + private final float scalingFactor; + private final float noiseAmount; // the amount of base noise to keep + private final int baseColourStrength; private final Gradient nebulaGradient; - public NebulaSkyboxPainter(PerlinNoise noise, Gradient nebula_gradient) { + public NebulaSkyboxPainter(PerlinNoise noise, Gradient nebulaGradient, float scalingFactor, float noiseAmount, int baseColourStrength) { super(noise); - nebulaGradient = nebula_gradient; + this.nebulaGradient = nebulaGradient; + + this.scalingFactor = scalingFactor; + this.noiseAmount = noiseAmount; + this.baseColourStrength = baseColourStrength; } @Override @@ -26,26 +30,34 @@ public class NebulaSkyboxPainter extends SkyboxPainter { z = projCoords[2]; // Get offset - float offset = (float) noise.getValue(x * SCALING_FACTOR * 3, y * SCALING_FACTOR * 3, z * SCALING_FACTOR * 3); + float offset = (float) noise.getValue(x * scalingFactor * 3, y * scalingFactor * 3, z * scalingFactor * 3); x = Mth.clamp(x + offset / 5f, -1f, 1f); y = Mth.clamp(y + offset / 5f, -1f, 1f); z = Mth.clamp(z + offset / 5f, -1f, 1f); // Value of noise at coord, 0..1 - double noiseValue = Mth.clamp(noise.getValue(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR) + 0.5, 0, 1); + double noiseValue = Mth.clamp(noise.getValue(x * scalingFactor, y * scalingFactor, z * scalingFactor) + 0.5, 0, 1); // Value to be subtracted from noise at coord, 0..1 - double subtractionValue = Mth.clamp(noise.getOctaveNoise(1).noise(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR) + 0.5, 0D, 1D); + double subtractionValue = Mth.clamp(noise.getOctaveNoise(1) + .noise(x * scalingFactor, y * scalingFactor, z * scalingFactor) + 0.5, 0D, 1D); double[] ds = new double[3]; - noise.getOctaveNoise(0).noiseWithDerivative(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR, ds); + noise.getOctaveNoise(0).noiseWithDerivative(x * scalingFactor, y * scalingFactor, z * scalingFactor, ds); // Find a base background colour to use (xyz interpoaltion across sky, gamer mode) - int baseB = (int) ((x / 2 + 0.5) * BASE_COLOUR_STRENGTH); - int baseG = (int) ((y / 2 + 0.5) * BASE_COLOUR_STRENGTH); - int baseR = (int) ((z / 2 + 0.5) * BASE_COLOUR_STRENGTH); + int baseB = (int) ((x / 2 + 0.5) * baseColourStrength); + int baseG = (int) ((y / 2 + 0.5) * baseColourStrength); + int baseR = (int) ((z / 2 + 0.5) * baseColourStrength); + + // Turn off nebula rendering if noiseAmount is 0. (user expected behaviour) + double nebulaFactor; + if (noiseAmount != 0) { + nebulaFactor = (Mth.clamp((noiseValue * (1D / noiseAmount) - (1D / noiseAmount - 1)), 0, 0.99)); + } else { + nebulaFactor = 0; + } - double nebulaFactor = (Mth.clamp((noiseValue * (1D / NOISE_AMOUNT) - (1D / NOISE_AMOUNT - 1)), 0, 0.99)); int[] nebula = nebulaGradient.getAt(nebulaFactor); double bgFactor = Mth.clamp(Math.log10(-nebulaFactor + 1) + 1, 0, 1);