From 17ea4985207df6148def1d3ffcea2b6b33f67f81 Mon Sep 17 00:00:00 2001 From: OreCruncher Date: Thu, 2 Jan 2025 08:54:15 -0800 Subject: [PATCH] Weight table cleanup; fog diagnostics; fix neoforge GUI layer registration --- .../dsurround/config/AcousticEntry.java | 13 ++-- .../dsurround/config/biome/BiomeInfo.java | 3 +- .../dsurround/config/data/AcousticConfig.java | 7 ++- .../dsurround/lib/WeightTable.java | 47 ++++---------- .../lib/collections/ObjectArray.java | 8 +-- .../dsurround/processing/FogHandler.java | 12 ++-- .../fog/BiomeFogRangeCalculator.java | 2 +- .../fog/HolisticFogRangeCalculator.java | 17 ++++++ .../fog/MorningFogRangeCalculator.java | 61 ++++++++----------- .../fog/WeatherFogRangeCalculator.java | 2 +- .../src/main/resources/dsurround.mixins.json | 1 - .../orecruncher/fabric/mixins}/MixinGui.java | 2 +- .../resources/dsurround.mixins.fabric.json | 15 +++++ fabric/src/main/resources/fabric.mod.json | 3 +- .../org/orecruncher/neoforge/NeoForgeMod.java | 13 ++++ 15 files changed, 113 insertions(+), 93 deletions(-) rename {common/src/main/java/org/orecruncher/dsurround/mixins/core => fabric/src/main/java/org/orecruncher/fabric/mixins}/MixinGui.java (96%) create mode 100644 fabric/src/main/resources/dsurround.mixins.fabric.json diff --git a/common/src/main/java/org/orecruncher/dsurround/config/AcousticEntry.java b/common/src/main/java/org/orecruncher/dsurround/config/AcousticEntry.java index 61018fac..5a043a8a 100644 --- a/common/src/main/java/org/orecruncher/dsurround/config/AcousticEntry.java +++ b/common/src/main/java/org/orecruncher/dsurround/config/AcousticEntry.java @@ -1,6 +1,8 @@ package org.orecruncher.dsurround.config; import com.google.common.base.MoreObjects; +import net.minecraft.util.random.Weight; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.orecruncher.dsurround.lib.WeightTable; import org.orecruncher.dsurround.lib.di.ContainerManager; @@ -11,9 +13,9 @@ public class AcousticEntry implements WeightTable.IItem { private static final IConditionEvaluator CONDITION_EVALUATOR = ContainerManager.resolve(IConditionEvaluator.class); - private static final int DEFAULT_WEIGHT = 10; + private static final Weight DEFAULT_WEIGHT = Weight.of(10); - private final int weight; + private final Weight weight; private final ISoundFactory acoustic; private final Script conditions; @@ -21,19 +23,20 @@ public AcousticEntry(final ISoundFactory acoustic, @Nullable final Script condit this(acoustic, condition, DEFAULT_WEIGHT); } - public AcousticEntry(final ISoundFactory acoustic, @Nullable final Script condition, int weight) { + public AcousticEntry(final ISoundFactory acoustic, @Nullable final Script condition, Weight weight) { this.acoustic = acoustic; this.weight = weight; this.conditions = condition != null ? condition : Script.TRUE; } + @NotNull @Override - public int getWeight() { + public Weight getWeight() { return this.weight; } @Override - public ISoundFactory getItem() { + public ISoundFactory data() { return getAcoustic(); } diff --git a/common/src/main/java/org/orecruncher/dsurround/config/biome/BiomeInfo.java b/common/src/main/java/org/orecruncher/dsurround/config/biome/BiomeInfo.java index 22862de6..237a6f7d 100644 --- a/common/src/main/java/org/orecruncher/dsurround/config/biome/BiomeInfo.java +++ b/common/src/main/java/org/orecruncher/dsurround/config/biome/BiomeInfo.java @@ -5,6 +5,7 @@ import net.minecraft.network.chat.TextColor; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.Music; +import net.minecraft.util.random.Weight; import net.minecraft.world.level.biome.Biome; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; @@ -242,7 +243,7 @@ public void update(final BiomeConfigRule entry) { targetCollection = this.loopSounds; } case MUSIC, MOOD, ADDITION -> { - final int weight = sr.weight(); + final Weight weight = sr.weight(); acousticEntry = new AcousticEntry(factory, sr.conditions(), weight); if (sr.type() == SoundEventType.ADDITION) diff --git a/common/src/main/java/org/orecruncher/dsurround/config/data/AcousticConfig.java b/common/src/main/java/org/orecruncher/dsurround/config/data/AcousticConfig.java index db8149b9..bb9abae2 100644 --- a/common/src/main/java/org/orecruncher/dsurround/config/data/AcousticConfig.java +++ b/common/src/main/java/org/orecruncher/dsurround/config/data/AcousticConfig.java @@ -3,6 +3,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.random.Weight; import org.orecruncher.dsurround.config.SoundEventType; import org.orecruncher.dsurround.lib.IdentityUtils; import org.orecruncher.dsurround.lib.scripting.Script; @@ -10,14 +11,16 @@ public record AcousticConfig( ResourceLocation factory, Script conditions, - Integer weight, + Weight weight, SoundEventType type) { + private static final Weight DEFAULT_WEIGHT = Weight.of(10); + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( IdentityUtils.CODEC.fieldOf("factory").forGetter(AcousticConfig::factory), Script.CODEC.optionalFieldOf("conditions", Script.TRUE).forGetter(AcousticConfig::conditions), - Codec.intRange(0, Integer.MAX_VALUE).optionalFieldOf("weight", 10).forGetter(AcousticConfig::weight), + Weight.CODEC.optionalFieldOf("weight", DEFAULT_WEIGHT).forGetter(AcousticConfig::weight), SoundEventType.CODEC.optionalFieldOf("type", SoundEventType.LOOP).forGetter(AcousticConfig::type) ).apply(instance, AcousticConfig::new)); } \ No newline at end of file diff --git a/common/src/main/java/org/orecruncher/dsurround/lib/WeightTable.java b/common/src/main/java/org/orecruncher/dsurround/lib/WeightTable.java index c0eeb7b4..3395ac62 100644 --- a/common/src/main/java/org/orecruncher/dsurround/lib/WeightTable.java +++ b/common/src/main/java/org/orecruncher/dsurround/lib/WeightTable.java @@ -1,10 +1,10 @@ package org.orecruncher.dsurround.lib; -import org.orecruncher.dsurround.lib.collections.ObjectArray; +import net.minecraft.util.random.WeightedEntry; +import net.minecraft.util.random.WeightedRandom; import org.orecruncher.dsurround.lib.random.IRandomizer; import org.orecruncher.dsurround.lib.random.Randomizer; -import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -12,58 +12,33 @@ /** * Classic WeightTable for random weighted selection. */ -@SuppressWarnings("unused") public class WeightTable { public static Optional makeSelection(final Stream> inputStream) { - return makeSelection(inputStream.toList(), Randomizer.current()); + return makeSelection(inputStream, Randomizer.current()); } public static Optional makeSelection(final Stream> inputStream, IRandomizer randomizer) { return makeSelection(inputStream.toList(), randomizer); } - public static Optional makeSelection(final Collection> selections) { - return makeSelection(selections, Randomizer.current()); - } - - public static Optional makeSelection(final Collection> selections, IRandomizer randomizer) { + public static Optional makeSelection(final List> selections, IRandomizer randomizer) { if (selections.isEmpty()) return Optional.empty(); - if (selections.size() == 1) { - T theItem; - if (selections instanceof List> theList) - theItem = theList.getFirst().getItem(); - else if (selections instanceof ObjectArray> theArray) - theItem = theArray.getFirst().getItem(); - else - theItem = selections.iterator().next().getItem(); - return Optional.of(theItem); - } + if (selections.size() == 1) + return Optional.of(selections.getFirst().data()); + + int totalWeight = WeightedRandom.getTotalWeight(selections); - int totalWeight = 0; - for (var e : selections) - totalWeight += e.getWeight(); if (totalWeight == 0) return Optional.empty(); int targetWeight = randomizer.nextInt(totalWeight); - - for (var e : selections) { - targetWeight -= e.getWeight(); - if (targetWeight < 0) - return Optional.of(e.getItem()); - } - - // Shouldn't get here - throw new RuntimeException("Bad weight table - ran off the end"); + return WeightedRandom.getWeightedItem(selections, targetWeight).map(IItem::data); } - public interface IItem { - - int getWeight(); - - T getItem(); + public interface IItem extends WeightedEntry { + T data(); } } \ No newline at end of file diff --git a/common/src/main/java/org/orecruncher/dsurround/lib/collections/ObjectArray.java b/common/src/main/java/org/orecruncher/dsurround/lib/collections/ObjectArray.java index c597a1d2..e987ede3 100644 --- a/common/src/main/java/org/orecruncher/dsurround/lib/collections/ObjectArray.java +++ b/common/src/main/java/org/orecruncher/dsurround/lib/collections/ObjectArray.java @@ -71,11 +71,11 @@ private void remove0(final int idx) { @SuppressWarnings("unchecked") @Override - public boolean removeIf(final Predicate pred) { + public boolean removeIf(@NotNull final Predicate filter) { boolean result = false; for (int i = this.insertionIdx - 1; i >= 0; i--) { final T t = (T) this.data[i]; - if (pred.test(t)) { + if (filter.test(t)) { result = true; this.remove0(i); } @@ -117,7 +117,7 @@ public boolean contains(final Object o) { return result; } - @SuppressWarnings({"unchecked", "hiding"}) + @SuppressWarnings({"unchecked", "TypeParameterHidesVisibleType"}) @Override public T @NotNull [] toArray(final T[] a) { // From ArrayList impl @@ -173,7 +173,7 @@ public boolean removeAll(final Collection c) { } @Override - public boolean retainAll(final Collection c) { + public boolean retainAll(@NotNull final Collection c) { return this.removeIf(entry -> !c.contains(entry)); } diff --git a/common/src/main/java/org/orecruncher/dsurround/processing/FogHandler.java b/common/src/main/java/org/orecruncher/dsurround/processing/FogHandler.java index 6f3a891d..4cdd3b1c 100644 --- a/common/src/main/java/org/orecruncher/dsurround/processing/FogHandler.java +++ b/common/src/main/java/org/orecruncher/dsurround/processing/FogHandler.java @@ -41,14 +41,18 @@ private void renderFog(FogRenderer.FogData data, float renderDistance, float par RenderSystem.setShaderFogStart(this.lastData.start); RenderSystem.setShaderFogEnd(this.lastData.end); RenderSystem.setShaderFogShape(this.lastData.shape); + } else { + // Preserve for diagnostic trace even though action was not taken + this.lastData = data; } } @Override protected void gatherDiagnostics(CollectDiagnosticsEvent event) { - if (this.fogCalculator.enabled()) - event.add(CollectDiagnosticsEvent.Section.Systems, "Fog: %f/%f, %s, %s".formatted(this.lastData.start, this.lastData.end, this.lastData.shape, this.lastData.mode)); - else - event.add(CollectDiagnosticsEvent.Section.Systems, "Fog: DISABLED"); + var text = "Fog: %f/%f, %s, %s ".formatted(this.lastData.start, this.lastData.end, this.lastData.shape, this.lastData.mode); + var disabledText = this.fogCalculator.getDisabledText(); + if (disabledText.isPresent()) + text += disabledText.get(); + event.add(CollectDiagnosticsEvent.Section.Systems, text); } } diff --git a/common/src/main/java/org/orecruncher/dsurround/processing/fog/BiomeFogRangeCalculator.java b/common/src/main/java/org/orecruncher/dsurround/processing/fog/BiomeFogRangeCalculator.java index 36f5ec1c..40732bf3 100644 --- a/common/src/main/java/org/orecruncher/dsurround/processing/fog/BiomeFogRangeCalculator.java +++ b/common/src/main/java/org/orecruncher/dsurround/processing/fog/BiomeFogRangeCalculator.java @@ -23,7 +23,7 @@ public class BiomeFogRangeCalculator extends VanillaFogRangeCalculator { private float targetScale; public BiomeFogRangeCalculator(IBiomeLibrary biomeLibrary, Configuration.FogOptions fogOptions) { - super("BiomeFogRangeCalculator", fogOptions); + super("Biome", fogOptions); this.biomeLibrary = biomeLibrary; this.activeScale = this.targetScale = 0F; this.lastBlockPos = BlockPos.ZERO; diff --git a/common/src/main/java/org/orecruncher/dsurround/processing/fog/HolisticFogRangeCalculator.java b/common/src/main/java/org/orecruncher/dsurround/processing/fog/HolisticFogRangeCalculator.java index 2969bd19..d855cccd 100644 --- a/common/src/main/java/org/orecruncher/dsurround/processing/fog/HolisticFogRangeCalculator.java +++ b/common/src/main/java/org/orecruncher/dsurround/processing/fog/HolisticFogRangeCalculator.java @@ -11,6 +11,9 @@ import org.orecruncher.dsurround.lib.logging.ModLog; import org.orecruncher.dsurround.lib.seasons.ISeasonalInformation; +import java.util.Optional; +import java.util.stream.Collectors; + public class HolisticFogRangeCalculator implements IFogRangeCalculator { protected final IModLog logger; @@ -78,4 +81,18 @@ public void tick() { public void disconnect() { this.calculators.forEach(IFogRangeCalculator::disconnect); } + + public Optional getDisabledText() { + if (!this.enabled()) { + return Optional.of("(ALL DISABLED)"); + } + + var result = this.calculators.stream().filter(e -> !e.enabled()).map(IFogRangeCalculator::getName).collect(Collectors.joining(", ")); + + if (result.isEmpty()) { + return Optional.empty(); + } + + return Optional.of("(DISABLED: " + result + ")"); + } } diff --git a/common/src/main/java/org/orecruncher/dsurround/processing/fog/MorningFogRangeCalculator.java b/common/src/main/java/org/orecruncher/dsurround/processing/fog/MorningFogRangeCalculator.java index 51db66ce..5bd92659 100644 --- a/common/src/main/java/org/orecruncher/dsurround/processing/fog/MorningFogRangeCalculator.java +++ b/common/src/main/java/org/orecruncher/dsurround/processing/fog/MorningFogRangeCalculator.java @@ -2,50 +2,37 @@ import net.minecraft.client.renderer.FogRenderer; import net.minecraft.util.Mth; +import net.minecraft.util.random.WeightedEntry; +import net.minecraft.util.random.WeightedRandom; import org.jetbrains.annotations.NotNull; import org.orecruncher.dsurround.Configuration; import org.orecruncher.dsurround.lib.GameUtils; import org.orecruncher.dsurround.lib.MinecraftClock; +import org.orecruncher.dsurround.lib.random.Randomizer; import org.orecruncher.dsurround.lib.seasons.ISeasonalInformation; -import org.orecruncher.dsurround.lib.WeightTable; import java.util.List; public class MorningFogRangeCalculator extends VanillaFogRangeCalculator { - private record FogDensityEntry(int weight, FogDensity density) implements WeightTable.IItem { - @Override - public int getWeight() { - return this.weight(); - } - @Override - public FogDensity getItem() { - return this.density(); - } - } + private static final List> SPRING_FOG = List.of( + WeightedEntry.wrap(FogDensity.NORMAL, 30), + WeightedEntry.wrap(FogDensity.MEDIUM, 20), + WeightedEntry.wrap(FogDensity.HEAVY, 10)); + + private static final List> SUMMER_FOG = List.of( + WeightedEntry.wrap(FogDensity.LIGHT, 20), + WeightedEntry.wrap(FogDensity.NONE, 10)); + + private static final List> AUTUMN_FOG = List.of( + WeightedEntry.wrap(FogDensity.NORMAL, 10), + WeightedEntry.wrap(FogDensity.MEDIUM, 20), + WeightedEntry.wrap(FogDensity.HEAVY, 10)); - private static final FogDensityEntry[] SPRING_FOG = { - new FogDensityEntry(30, FogDensity.NORMAL), - new FogDensityEntry(20, FogDensity.MEDIUM), - new FogDensityEntry(10, FogDensity.HEAVY) - }; - - private static final FogDensityEntry[] SUMMER_FOG = { - new FogDensityEntry(20, FogDensity.LIGHT), - new FogDensityEntry(10, FogDensity.NONE) - }; - - private static final FogDensityEntry[] AUTUMN_FOG = { - new FogDensityEntry(10, FogDensity.NORMAL), - new FogDensityEntry(20, FogDensity.MEDIUM), - new FogDensityEntry(10, FogDensity.HEAVY) - }; - - private static final FogDensityEntry[] WINTER_FOG = { - new FogDensityEntry(20, FogDensity.LIGHT), - new FogDensityEntry(20, FogDensity.NORMAL), - new FogDensityEntry(10, FogDensity.MEDIUM) - }; + private static final List> WINTER_FOG = List.of( + WeightedEntry.wrap(FogDensity.LIGHT, 20), + WeightedEntry.wrap(FogDensity.NORMAL, 20), + WeightedEntry.wrap(FogDensity.MEDIUM, 10)); protected final ISeasonalInformation seasonInfo; protected final MinecraftClock clock; @@ -53,7 +40,7 @@ public FogDensity getItem() { protected FogDensity type = FogDensity.NONE; public MorningFogRangeCalculator(ISeasonalInformation seasonInfo, Configuration.FogOptions fogOptions) { - super("MorningFogRangeCalculator", fogOptions); + super("Morning", fogOptions); this.seasonInfo = seasonInfo; this.clock = new MinecraftClock(); } @@ -112,7 +99,7 @@ private float getCelestialAngleDegrees() { @NotNull protected FogDensity getFogType() { - FogDensityEntry[] selections; + List> selections; var clientLevel = GameUtils.getWorld().orElseThrow(); if (this.seasonInfo.isSpring(clientLevel)) selections = SPRING_FOG; @@ -126,6 +113,8 @@ else if (this.seasonInfo.isWinter(clientLevel)) // Shouldn't get here, but... return FogDensity.NONE; - return WeightTable.makeSelection(List.of(selections)).orElseThrow(); + var totalWeight = WeightedRandom.getTotalWeight(selections); + var targetWeight = Randomizer.current().nextInt(totalWeight); + return WeightedRandom.getWeightedItem(selections, targetWeight).map(WeightedEntry.Wrapper::data).orElseThrow(); } } \ No newline at end of file diff --git a/common/src/main/java/org/orecruncher/dsurround/processing/fog/WeatherFogRangeCalculator.java b/common/src/main/java/org/orecruncher/dsurround/processing/fog/WeatherFogRangeCalculator.java index bb788980..952cbfda 100644 --- a/common/src/main/java/org/orecruncher/dsurround/processing/fog/WeatherFogRangeCalculator.java +++ b/common/src/main/java/org/orecruncher/dsurround/processing/fog/WeatherFogRangeCalculator.java @@ -11,7 +11,7 @@ public class WeatherFogRangeCalculator extends VanillaFogRangeCalculator { protected static final float END_IMPACT = 0.4F; protected WeatherFogRangeCalculator(Configuration.FogOptions fogOptions) { - super("WeatherFogRangeCalculator", fogOptions); + super("Weather", fogOptions); } @Override diff --git a/common/src/main/resources/dsurround.mixins.json b/common/src/main/resources/dsurround.mixins.json index 63b03da2..0842a487 100644 --- a/common/src/main/resources/dsurround.mixins.json +++ b/common/src/main/resources/dsurround.mixins.json @@ -27,7 +27,6 @@ "core.MixinEntity", "core.MixinEntityArrow", "core.MixinFogRenderer", - "core.MixinGui", "core.MixinLivingEntity", "core.MixinParticleManager", "core.MixinRainSplashParticle", diff --git a/common/src/main/java/org/orecruncher/dsurround/mixins/core/MixinGui.java b/fabric/src/main/java/org/orecruncher/fabric/mixins/MixinGui.java similarity index 96% rename from common/src/main/java/org/orecruncher/dsurround/mixins/core/MixinGui.java rename to fabric/src/main/java/org/orecruncher/fabric/mixins/MixinGui.java index ff4e810b..a3e89844 100644 --- a/common/src/main/java/org/orecruncher/dsurround/mixins/core/MixinGui.java +++ b/fabric/src/main/java/org/orecruncher/fabric/mixins/MixinGui.java @@ -1,4 +1,4 @@ -package org.orecruncher.dsurround.mixins.core; +package org.orecruncher.fabric.mixins; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; diff --git a/fabric/src/main/resources/dsurround.mixins.fabric.json b/fabric/src/main/resources/dsurround.mixins.fabric.json new file mode 100644 index 00000000..a61f1c57 --- /dev/null +++ b/fabric/src/main/resources/dsurround.mixins.fabric.json @@ -0,0 +1,15 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "org.orecruncher.fabric.mixins", + "compatibilityLevel": "JAVA_21", + "mixins": [ + ], + "client": [ + "MixinGui" + ], + "server": [], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index d8671640..7c2d0530 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -23,7 +23,8 @@ ] }, "mixins": [ - "dsurround.mixins.json" + "dsurround.mixins.json", + "dsurround.mixins.fabric.json" ], "depends": { "fabricloader": ">=0.16.9", diff --git a/neoforge/src/main/java/org/orecruncher/neoforge/NeoForgeMod.java b/neoforge/src/main/java/org/orecruncher/neoforge/NeoForgeMod.java index d3a1a7cd..80b50426 100644 --- a/neoforge/src/main/java/org/orecruncher/neoforge/NeoForgeMod.java +++ b/neoforge/src/main/java/org/orecruncher/neoforge/NeoForgeMod.java @@ -1,5 +1,6 @@ package org.orecruncher.neoforge; +import net.minecraft.resources.ResourceLocation; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; @@ -8,9 +9,12 @@ import net.neoforged.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent; import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import org.orecruncher.dsurround.Client; import org.orecruncher.dsurround.Constants; +import org.orecruncher.dsurround.gui.overlay.OverlayManager; +import org.orecruncher.dsurround.lib.di.ContainerManager; @Mod(value = Constants.MOD_ID, dist = Dist.CLIENT) public final class NeoForgeMod { @@ -19,6 +23,7 @@ public final class NeoForgeMod { public NeoForgeMod(ModContainer container, IEventBus modBus) { modBus.addListener(this::onInitializeClient); + modBus.addListener(this::onRegisterGuiLayersEvent); this.client = new Client(); this.client.construct(); @@ -26,6 +31,14 @@ public NeoForgeMod(ModContainer container, IEventBus modBus) { if (ModList.get().isLoaded(Constants.CLOTH_CONFIG_NEOFORGE)) container.registerExtensionPoint(IConfigScreenFactory.class, new ModConfigMenu()); + + } + + @SubscribeEvent + public void onRegisterGuiLayersEvent(RegisterGuiLayersEvent event) { + // Add the overlay manager to the render layers of Gui + OverlayManager dsurround_overlayManager = ContainerManager.resolve(OverlayManager.class); + event.registerBelowAll(ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "layer/overlaymanager"), dsurround_overlayManager::render); } @SubscribeEvent