diff --git a/src/main/java/dev/micle/firefly_bush_backport/block/FireflyBushBlock.java b/src/main/java/dev/micle/firefly_bush_backport/block/FireflyBushBlock.java index 8a2cab3..4ba0ded 100644 --- a/src/main/java/dev/micle/firefly_bush_backport/block/FireflyBushBlock.java +++ b/src/main/java/dev/micle/firefly_bush_backport/block/FireflyBushBlock.java @@ -1,5 +1,6 @@ package dev.micle.firefly_bush_backport.block; +import dev.micle.firefly_bush_backport.config.Config; import dev.micle.firefly_bush_backport.particle.ModParticles; import dev.micle.firefly_bush_backport.sound.ModSounds; import net.minecraft.core.BlockPos; @@ -19,12 +20,6 @@ import java.util.List; import java.util.Optional; public class FireflyBushBlock extends BushBlock implements BonemealableBlock { - private static final double FIREFLY_CHANCE_PER_TICK = 0.7; - private static final double FIREFLY_HORIZONTAL_RANGE = 10.0; - private static final double FIREFLY_VERTICAL_RANGE = 5.0; - private static final int FIREFLY_SPAWN_MAX_BRIGHTNESS_LEVEL = 13; - private static final int FIREFLY_AMBIENT_SOUND_CHANCE_ONE_IN = 30; - public FireflyBushBlock(Properties properties) { super(properties); } @@ -32,17 +27,22 @@ public class FireflyBushBlock extends BushBlock implements BonemealableBlock { @Override @ParametersAreNonnullByDefault public void animateTick(BlockState blockState, Level level, BlockPos blockPos, RandomSource randomSource) { - if (randomSource.nextInt(FIREFLY_AMBIENT_SOUND_CHANCE_ONE_IN) == 0 - && isMoonVisible(level) - && level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos.getX(), blockPos.getZ()) <= blockPos.getY()) { - level.playLocalSound(blockPos, ModSounds.FIREFLY_BUSH_IDLE.get(), SoundSource.AMBIENT, 1.0F, 1.0F, false); + if (randomSource.nextInt(Config.Client.bushFireflyAmbientSoundChanceOneIn.get()) == 0 && ( + Config.Client.bushExtraAlwaysPlayAmbientSound.get() || + (isMoonVisible(level) && level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos.getX(), blockPos.getZ()) <= blockPos.getY()) + )) { + level.playLocalSound( + blockPos, ModSounds.FIREFLY_BUSH_IDLE.get(), SoundSource.AMBIENT, 1.0F, 1.0F, false + ); } - if ((isMoonVisible(level) || level.getMaxLocalRawBrightness(blockPos) <= FIREFLY_SPAWN_MAX_BRIGHTNESS_LEVEL) && - randomSource.nextDouble() <= FIREFLY_CHANCE_PER_TICK) { - double d0 = blockPos.getX() + randomSource.nextDouble() * FIREFLY_HORIZONTAL_RANGE - FIREFLY_VERTICAL_RANGE; - double d1 = blockPos.getY() + randomSource.nextDouble() * FIREFLY_VERTICAL_RANGE; - double d2 = blockPos.getZ() + randomSource.nextDouble() * FIREFLY_HORIZONTAL_RANGE - FIREFLY_VERTICAL_RANGE; + if (randomSource.nextDouble() <= Config.Client.bushFireflyChancePerTick.get() && ( + Config.Client.bushExtraAlwaysSpawnParticles.get() || + (isMoonVisible(level) || level.getMaxLocalRawBrightness(blockPos) <= Config.Client.bushFireflySpawnMaxBrightnessLevel.get()) + )) { + double d0 = blockPos.getX() + randomSource.nextDouble() * Config.Client.bushFireflyHorizontalRange.get() - Config.Client.bushFireflyVerticalRange.get(); + double d1 = blockPos.getY() + randomSource.nextDouble() * Config.Client.bushFireflyVerticalRange.get(); + double d2 = blockPos.getZ() + randomSource.nextDouble() * Config.Client.bushFireflyHorizontalRange.get() - Config.Client.bushFireflyVerticalRange.get(); level.addParticle(ModParticles.FIREFLY.get(), d0, d1, d2, 0.0, 0.0, 0.0); } } diff --git a/src/main/java/dev/micle/firefly_bush_backport/config/Config.java b/src/main/java/dev/micle/firefly_bush_backport/config/Config.java index 025604a..3ec34fa 100644 --- a/src/main/java/dev/micle/firefly_bush_backport/config/Config.java +++ b/src/main/java/dev/micle/firefly_bush_backport/config/Config.java @@ -1,6 +1,8 @@ package dev.micle.firefly_bush_backport.config; import dev.micle.firefly_bush_backport.FireflyBushBackport; +import net.minecraft.util.random.SimpleWeightedRandomList; +import net.minecraft.world.level.Level; import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -8,6 +10,9 @@ import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.config.ModConfigEvent; import org.apache.commons.lang3.tuple.Pair; +import java.awt.*; +import java.util.List; + @Mod.EventBusSubscriber(modid = FireflyBushBackport.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) public final class Config { public static final Client CLIENT; @@ -49,9 +54,89 @@ public final class Config { } public static class Client { - Client(ForgeConfigSpec.Builder builder) {} + public static ForgeConfigSpec.DoubleValue bushFireflyChancePerTick; + public static ForgeConfigSpec.DoubleValue bushFireflyHorizontalRange; + public static ForgeConfigSpec.DoubleValue bushFireflyVerticalRange; + public static ForgeConfigSpec.IntValue bushFireflySpawnMaxBrightnessLevel; + public static ForgeConfigSpec.IntValue bushFireflyAmbientSoundChanceOneIn; - private static void onConfigReload() {} + public static ForgeConfigSpec.BooleanValue bushExtraAlwaysPlayAmbientSound; + public static ForgeConfigSpec.BooleanValue bushExtraAlwaysSpawnParticles; + + public static ForgeConfigSpec.DoubleValue particleFadeOutLightTime; + public static ForgeConfigSpec.DoubleValue particleFadeInLightTime; + public static ForgeConfigSpec.DoubleValue particleFadeOutAlphaTime; + public static ForgeConfigSpec.DoubleValue particleFadeInAlphaTime; + public static ForgeConfigSpec.IntValue particleMinLifetime; + public static ForgeConfigSpec.IntValue particleMaxLifetime; + + public static ForgeConfigSpec.DoubleValue particleExtraFriction; + public static ForgeConfigSpec.DoubleValue particleExtraScale; + public static ForgeConfigSpec.DoubleValue particleExtraBrightness; + private static ForgeConfigSpec.ConfigValue> particleExtraColors; + public static SimpleWeightedRandomList particleExtraColorsWeightedList; + + Client(ForgeConfigSpec.Builder builder) { + builder.comment("Settings for the firefly bush.").push("bush"); + bushFireflyChancePerTick = builder + .defineInRange("bushFireflyChancePerTick", 0.7, 0, 1); + bushFireflyHorizontalRange = builder + .defineInRange("bushFireflyHorizontalRange", 10.0, 0, Double.MAX_VALUE); + bushFireflyVerticalRange = builder + .defineInRange("bushFireflyVerticalRange", 5.0, 0, Double.MAX_VALUE); + bushFireflySpawnMaxBrightnessLevel = builder + .defineInRange("bushFireflySpawnMaxBrightnessLevel", 13, 0, Level.MAX_BRIGHTNESS); + bushFireflyAmbientSoundChanceOneIn = builder + .defineInRange("bushFireflyAmbientSoundChanceOneIn", 30, 0, Integer.MAX_VALUE); + + builder.comment("Extra settings for the firefly bush.").push("extra"); + bushExtraAlwaysPlayAmbientSound = builder + .define("bushExtraAlwaysPlayAmbientSound", false); + bushExtraAlwaysSpawnParticles = builder + .define("bushExtraAlwaysSpawnParticles", false); + builder.pop(); + builder.pop(); + + builder.comment("Settings for the firefly particle.").push("particle"); + particleFadeOutLightTime = builder + .defineInRange("particleFadeOutLightTime", 0.3, 0, 1.0); + particleFadeInLightTime = builder + .defineInRange("particleFadeInLightTime", 0.1, 0, 1.0); + particleFadeOutAlphaTime = builder + .defineInRange("particleFadeOutAlphaTime", 0.5, 0, 1.0); + particleFadeInAlphaTime = builder + .defineInRange("particleFadeInAlphaTime", 0.3, 0, 1.0); + particleMinLifetime = builder + .defineInRange("particleMinLifetime", 36, 0, Integer.MAX_VALUE); + particleMaxLifetime = builder + .defineInRange("particleMaxLifetime", 180, 0, Integer.MAX_VALUE); + + builder.comment("Extra settings for the firefly particle.").push("extra"); + particleExtraFriction = builder + .defineInRange("particleExtraFriction", 0.96, 0, Double.MAX_VALUE); + particleExtraScale = builder + .defineInRange("particleExtraScale", 0.75, 0, Double.MAX_VALUE); + particleExtraBrightness = builder + .defineInRange("particleExtraBrightness", 255.0, 0, 255); + particleExtraColors = builder + .comment("List of color hex values and their weight. Format: ','") + .defineList("particleExtraColors", List.of("#ffffff,1"), Client::isValidColorEntry); + builder.pop(); + builder.pop(); + } + + private static void onConfigReload() { + SimpleWeightedRandomList.Builder particleExtraColorsWeightedListBuilder = SimpleWeightedRandomList.builder(); + for (String entry : particleExtraColors.get()) { + String[] splitEntry = entry.split(","); + particleExtraColorsWeightedListBuilder.add(Color.decode(splitEntry[0]), Integer.parseInt(splitEntry[1])); + } + particleExtraColorsWeightedList = particleExtraColorsWeightedListBuilder.build(); + } + + private static boolean isValidColorEntry(Object entry) { + return entry instanceof String && ((String) entry).matches("#\\w{6},\\d+$"); + } } public static class Common { diff --git a/src/main/java/dev/micle/firefly_bush_backport/particle/FireflyParticle.java b/src/main/java/dev/micle/firefly_bush_backport/particle/FireflyParticle.java index 703326a..d041953 100644 --- a/src/main/java/dev/micle/firefly_bush_backport/particle/FireflyParticle.java +++ b/src/main/java/dev/micle/firefly_bush_backport/particle/FireflyParticle.java @@ -1,5 +1,6 @@ package dev.micle.firefly_bush_backport.particle; +import dev.micle.firefly_bush_backport.config.Config; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.particle.*; import net.minecraft.core.BlockPos; @@ -10,21 +11,16 @@ import net.minecraftforge.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; import javax.annotation.ParametersAreNonnullByDefault; +import java.awt.*; +import java.util.Optional; @OnlyIn(Dist.CLIENT) public class FireflyParticle extends TextureSheetParticle { - private static final float PARTICLE_FADE_OUT_LIGHT_TIME = 0.3F; - private static final float PARTICLE_FADE_IN_LIGHT_TIME = 0.1F; - private static final float PARTICLE_FADE_OUT_ALPHA_TIME = 0.5F; - private static final float PARTICLE_FADE_IN_ALPHA_TIME = 0.3F; - private static final int PARTICLE_MIN_LIFETIME = 36; - private static final int PARTICLE_MAX_LIFETIME = 180; - protected FireflyParticle(ClientLevel clientLevel, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { super(clientLevel, x, y, z, xSpeed, ySpeed, zSpeed); this.speedUpWhenYMotionIsBlocked = true; - this.friction = 0.96F; - this.quadSize *= 0.75F; + this.friction = Config.Client.particleExtraFriction.get().floatValue(); + this.quadSize *= Config.Client.particleExtraScale.get().floatValue(); this.yd *= 0.8F; this.xd *= 0.8F; this.zd *= 0.8F; @@ -37,7 +33,11 @@ public class FireflyParticle extends TextureSheetParticle { @Override public int getLightColor(float partialTick) { - return (int) (255.0F * getFadeAmount(this.getLifetimeProgress(this.age + partialTick), PARTICLE_FADE_IN_LIGHT_TIME, PARTICLE_FADE_OUT_LIGHT_TIME)); + return (int) (Config.Client.particleExtraBrightness.get().floatValue() * getFadeAmount( + this.getLifetimeProgress(this.age + partialTick), + Config.Client.particleFadeInLightTime.get().floatValue(), + Config.Client.particleFadeOutLightTime.get().floatValue()) + ); } private static float getFadeAmount(float lifetimeProgress, float fadeIn, float fadeOut) { @@ -58,7 +58,10 @@ public class FireflyParticle extends TextureSheetParticle { if (!this.level.getBlockState(BlockPos.containing(this.x, this.y, this.z)).isAir()) { this.remove(); } else { - this.setAlpha(getFadeAmount(this.getLifetimeProgress(this.age), PARTICLE_FADE_IN_ALPHA_TIME, PARTICLE_FADE_OUT_ALPHA_TIME)); + this.setAlpha(getFadeAmount(this.getLifetimeProgress(this.age), + Config.Client.particleFadeInAlphaTime.get().floatValue(), + Config.Client.particleFadeOutAlphaTime.get().floatValue()) + ); if (Math.random() > 0.95 || this.age == 1) { this.setParticleSpeed(-0.05F + 0.1F * Math.random(), -0.05F + 0.1F * Math.random(), -0.05F + 0.1F * Math.random()); } @@ -93,11 +96,18 @@ public class FireflyParticle extends TextureSheetParticle { clientLevel.random.nextBoolean() ? ySpeed : -ySpeed, 0.5 - clientLevel.random.nextDouble() ); - fireflyParticle.setLifetime(clientLevel.random.nextIntBetweenInclusive(PARTICLE_MIN_LIFETIME, PARTICLE_MAX_LIFETIME)); + fireflyParticle.setLifetime(clientLevel.random.nextIntBetweenInclusive( + Config.Client.particleMinLifetime.get(), Config.Client.particleMaxLifetime.get() + )); fireflyParticle.scale(1.5F); fireflyParticle.pickSprite(this.sprite); fireflyParticle.setAlpha(0.0F); + Optional optionalColor = Config.Client.particleExtraColorsWeightedList.getRandomValue(clientLevel.random); + optionalColor.ifPresent(color -> + fireflyParticle.setColor(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F) + ); + return fireflyParticle; } }