Skip to content

Commit

Permalink
OreCruncher/fog feature (#133)
Browse files Browse the repository at this point in the history
* Release update

* Initial checking of fog effects

* Rework fog into handler

* Morning fog weight table; fix ISC menu crash

* Bump version and docs

* Minor refactor/cleanup of biome sound emitter

* Add turtledove spot sound for forests of different types

* Add silent forest track; detect duplicate sounds during config

* Pause/unpause music manager command

* Powered redstone; more tweaks

* Adjust electric arc volume

---------

Co-authored-by: OreCruncher <[email protected]>
  • Loading branch information
OreCruncher and OreCruncher authored Dec 30, 2024
1 parent 0eed352 commit 4fbe3fa
Show file tree
Hide file tree
Showing 55 changed files with 1,019 additions and 63 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
> ### DynamicSurroundings-1.21.1-0.4.1
**All Loaders**
* JAVA 21+
* Architectury 13.0.8+

**Fabric**
* Fabric Loader >= 0.16.9
* Fabric API >= 0.110.0+1.21.

**NeoForge**
* NeoForge 21.1.84+

**What's New**
* Added capability to pause/unpause music manager using the /dsmm command.
* Fog effects - Several different types of fog
* Morning fog Occurs early in the AM and eventually burns off
* Weather fog when raining
* Biome fog rendered in the fog color of the biome
* Turtledove sound effect for most forests
* Silent forest biome sound for forests that are snowy/cold (like snowy taiga). It's fairly quiet - light wind blowing through.
* Powered redstone has a chance of emitting an electric arc sound effect.

**Fixes**
* Individual Sound Configuration menu crash when rendering sounds from resource pack.
* Badlands have sound again. (Mesa -> Badlands transition had some challenges.)

> ### DynamicSurroundings-1.21.1-0.4.0
**All Loaders**
* JAVA 21+
Expand Down
12 changes: 12 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,15 @@ whether LPs can be monetized on the various streaming services.
<ul>
<li>S: <a href="https://www.freesound.org/people/reinsamba/sounds/58237/">MerlothPark_morning_ambiance.wav</a> by <a href="https://www.freesound.org/people/reinsamba/">reinsamba</a> | License: Attribution</li>
</ul>

*dsurround:turtledove*

<ul>
<li>S: <a href="https://freesound.org/people/csengeri/sounds/351726/">turtledove sounds</a> by <a href="https://freesound.org/people/csengeri/">csengeri</a> | License: Creative Commons 0</li>
</ul>

*dsurround:biome.forest.silent*

<ul>
<li>S: <a href="https://freesound.org/people/ZHR%C3%98/sounds/753418/">Silent forest</a> by <a href="https://freesound.org/people/ZHR%C3%98/">ZHRØ</a> | License: Creative Commons 0</li>
</ul>
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
> # Dynamic Surroundings for Fabric and NeoForge
A Minecraft Mod that alters the fabric of Minecraft experience by weaving a tapestry of sound and visual effects.

<a href="https://www.curseforge.com/minecraft/mc-mods/dynamic-surroundings"><img src="http://cf.way2muchnoise.eu/versions/238891.svg" alt="CurseForge Project"/></a>
<a href="https://www.curseforge.com/minecraft/mc-mods/dynamic-surroundings"><img src="http://cf.way2muchnoise.eu/full_238891_downloads.svg" alt="CurseForge Project"/></a>
<a href="https://modrinth.com/mod/dynamicsurroundingsfabric"><img src="https://img.shields.io/badge/Mod-rinth-brightgreen" alt="Modrinth"></a>
<div style="text-align: center;">
<a href="https://www.curseforge.com/minecraft/mc-mods/dynamic-surroundings"><img src="http://cf.way2muchnoise.eu/versions/238891.svg" alt="CurseForge Project"/></a>
<a href="https://www.curseforge.com/minecraft/mc-mods/dynamic-surroundings"><img src="http://cf.way2muchnoise.eu/full_238891_downloads.svg" alt="CurseForge Project"/></a>
</div>

<div style="text-align: center;">
<a href="https://modrinth.com/mod/dynamicsurroundingsfabric"><img src="https://img.shields.io/modrinth/game-versions/H7fshfpD?style=flat&label=Available%20for&color=%2300AF5C" alt="Modrinth"></a>
<a href="https://modrinth.com/mod/dynamicsurroundingsfabric"><img src="https://img.shields.io/modrinth/dt/H7fshfpD?style=flat&logo=modrinth&label=downloads" alt="Modrinth"></a>
</div>

This mod is a successor to the Forge-based Dynamic Surroundings series.
Though a lot of the functionality is similar, the ultimate feature set will be different.
Expand All @@ -15,6 +21,10 @@ The mod is 100% client side. You can add to any mod pack, whether you play stand

Starting with Minecraft 1.21.1, Dynamic Surroundings is supported on Fabric and NeoForge.

Online documentation: https://dynamic-surroundings.readthedocs.io/en/latest/index.html

Documentation repository: https://github.com/OreCruncher/DynamicSurroundingsDocs

### Minecraft 1.21.1 Requirements
* JAVA 21+
* Architectury 13.0.8+
Expand Down
6 changes: 6 additions & 0 deletions common/src/main/java/org/orecruncher/dsurround/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.orecruncher.dsurround.lib.version.VersionChecker;
import org.orecruncher.dsurround.lib.version.VersionResult;
import org.orecruncher.dsurround.processing.Handlers;
import org.orecruncher.dsurround.processing.fog.HolisticFogRangeCalculator;
import org.orecruncher.dsurround.runtime.ConditionEvaluator;
import org.orecruncher.dsurround.runtime.IConditionEvaluator;
import org.orecruncher.dsurround.sound.AudioPlayerDebug;
Expand Down Expand Up @@ -119,6 +120,7 @@ public void initializeClient() {
.registerSingleton(Config.footstepAccents)
.registerSingleton(Config.particleTweaks)
.registerSingleton(Config.compassAndClockOptions)
.registerSingleton(Config.fogOptions)
.registerSingleton(Config.otherOptions)
.registerSingleton(IConditionEvaluator.class, ConditionEvaluator.class)
.registerSingleton(IVersionChecker.class, VersionChecker.class)
Expand Down Expand Up @@ -170,6 +172,10 @@ public void onComplete(Minecraft client) {
AssetLibraryEvent.RELOAD.raise().onReload(resourceUtilities, IReloadEvent.Scope.TAGS);
}, HandlerPriority.VERY_HIGH);

// Add our fog handler
container.registerSingleton(HolisticFogRangeCalculator.class);
ContainerManager.resolve(HolisticFogRangeCalculator.class);

// Force instantiation of the core Handler. This should cause the rest
// of the dependencies to be initialized.
container.resolve(Handlers.class);
Expand Down
22 changes: 22 additions & 0 deletions common/src/main/java/org/orecruncher/dsurround/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public class Configuration extends ConfigurationData {
@Comment("Configuration options for the compass and clock overlay")
public final CompassAndClockOptions compassAndClockOptions = new CompassAndClockOptions();

@Property
@Comment("Configuration options for fog effects")
public final FogOptions fogOptions = new FogOptions();

@Property
@Comment("Configuration options for other things")
public final OtherOptions otherOptions = new OtherOptions();
Expand Down Expand Up @@ -287,6 +291,24 @@ public static class CompassAndClockOptions {
public double scale = 1D;
}

public static class FogOptions {
@Property
@Comment("Enable/disable fog effects")
public boolean enableFogEffects = true;

@Property
@Comment("Enable/disable morning fog effect")
public boolean enableMorningFog = true;

@Property
@Comment("Enable/disable biome fog effect")
public boolean enableBiomeFog = true;

@Property
@Comment("Enable/disable weather fog effect")
public boolean enableWeatherFog = true;
}

public static class OtherOptions {
@Property
@Comment("Enable/disable playing random sound at the Minecraft finish loading to main screen")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
public class MusicManagerCommand extends AbstractClientCommand {
private static final String COMMAND = "dsmm";
private static final String RESET = "reset";
private static final String PAUSE = "pause";
private static final String UNPAUSE = "unpause";

@Override
public void register(CommandDispatcher<ClientCommandRegistrationEvent.ClientCommandSourceStack> dispatcher, CommandBuildContext registryAccess) {
dispatcher.register(ClientCommandRegistrationEvent.literal(COMMAND)
.then(subCommand(RESET, MusicManagerCommandHandler::reset)));
.then(subCommand(RESET, MusicManagerCommandHandler::reset))
.then(subCommand(PAUSE, MusicManagerCommandHandler::pause))
.then(subCommand(UNPAUSE, MusicManagerCommandHandler::unpause)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,28 @@ public class MusicManagerCommandHandler {

public static Component reset() {
try {
((IMusicManager)(GameUtils.getMC().getMusicManager())).dsurround_reset();
((IMusicManager)(GameUtils.getMC().getMusicManager())).dsurround_doCommand("reset");
return Component.translatable("dsurround.command.dsmm.reset.success");
} catch (Throwable t) {
return Component.translatable("dsurround.command.dsmm.reset.failure", t.getMessage());
}
}

public static Component unpause() {
try {
((IMusicManager)(GameUtils.getMC().getMusicManager())).dsurround_doCommand("unpause");
return Component.translatable("dsurround.command.dsmm.unpause.success");
} catch (Throwable t) {
return Component.translatable("dsurround.command.dsmm.unpause.failure", t.getMessage());
}
}

public static Component pause() {
try {
((IMusicManager)(GameUtils.getMC().getMusicManager())).dsurround_doCommand("pause");
return Component.translatable("dsurround.command.dsmm.pause.success");
} catch (Throwable t) {
return Component.translatable("dsurround.command.dsmm.pause.failure", t.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.orecruncher.dsurround.config.biome;
package org.orecruncher.dsurround.config;

import com.google.common.base.MoreObjects;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -53,6 +53,19 @@ protected Script getConditionsForLogging() {
return getConditions();
}

@Override
public int hashCode() {
return this.conditions.hashCode() * 31 + this.acoustic.getLocation().hashCode();
}

@Override
public boolean equals(Object o) {
if (o instanceof AcousticEntry ae) {
return ae.conditions.equals(this.conditions) && ae.acoustic.getLocation().equals(this.acoustic.getLocation());
}
return false;
}

public String toString() {
return MoreObjects.toStringHelper(this)
.addValue(getWeight())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.orecruncher.dsurround.config;

import org.orecruncher.dsurround.lib.collections.ObjectArray;

public class AcousticEntryCollection extends ObjectArray<AcousticEntry> {

@Override
public boolean add(AcousticEntry entry) {
if (this.contains(entry))
return false;

return super.add(entry);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import net.minecraft.world.level.biome.Biome;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.orecruncher.dsurround.config.AcousticEntry;
import org.orecruncher.dsurround.config.AcousticEntryCollection;
import org.orecruncher.dsurround.config.data.AcousticConfig;
import org.orecruncher.dsurround.config.libraries.ISoundLibrary;
import org.orecruncher.dsurround.config.libraries.ITagLibrary;
Expand All @@ -24,6 +26,7 @@
import org.orecruncher.dsurround.lib.logging.IModLog;
import org.orecruncher.dsurround.lib.scripting.Script;
import org.orecruncher.dsurround.mixinutils.IBiomeExtended;
import org.orecruncher.dsurround.processing.fog.FogDensity;
import org.orecruncher.dsurround.runtime.IConditionEvaluator;
import org.orecruncher.dsurround.sound.ISoundFactory;

Expand All @@ -33,8 +36,7 @@

public final class BiomeInfo implements Comparable<BiomeInfo>, IBiomeSoundProvider {

public static final int DEFAULT_ADDITIONAL_SOUND_CHANCE = 1000 / 4;
public static final Script DEFAULT_SOUND_CHANCE = new Script(String.valueOf(1D / DEFAULT_ADDITIONAL_SOUND_CHANCE));
public static final Script DEFAULT_SOUND_CHANCE = new Script("0.008");
private static final IModLog LOGGER = ModLog.createChild(ContainerManager.resolve(IModLog.class), "BiomeInfo");
private static final ISoundLibrary SOUND_LIBRARY = ContainerManager.resolve(ISoundLibrary.class);
private static final ITagLibrary TAG_LIBRARY = ContainerManager.resolve(ITagLibrary.class);
Expand All @@ -49,12 +51,13 @@ public final class BiomeInfo implements Comparable<BiomeInfo>, IBiomeSoundProvid
private final boolean isOcean;
private final boolean isDeepOcean;
private final boolean isCave;
private Collection<AcousticEntry> loopSounds = new ObjectArray<>();
private Collection<AcousticEntry> moodSounds = new ObjectArray<>();
private Collection<AcousticEntry> additionalSounds = new ObjectArray<>();
private Collection<AcousticEntry> musicSounds = new ObjectArray<>();
private Collection<AcousticEntry> loopSounds = new AcousticEntryCollection();
private Collection<AcousticEntry> moodSounds = new AcousticEntryCollection();
private Collection<AcousticEntry> additionalSounds = new AcousticEntryCollection();
private Collection<AcousticEntry> musicSounds = new AcousticEntryCollection();
private Collection<String> comments = new ObjectArray<>();
private TextColor fogColor;
private FogDensity fogDensity;
private Script additionalSoundChance = DEFAULT_SOUND_CHANCE;
private Script moodSoundChance = DEFAULT_SOUND_CHANCE;

Expand All @@ -74,6 +77,8 @@ public BiomeInfo(final int version, final ResourceLocation id, final String name
this.isDeepOcean = this.isOcean && this.traits.contains(BiomeTrait.DEEP);
this.isCave = this.traits.contains(BiomeTrait.CAVES);

this.fogDensity = FogDensity.NONE;

// Check to see if the biome has a soundtrack. If so, add it to
// the music list.
if (biome != null) {
Expand Down Expand Up @@ -129,6 +134,14 @@ void setFogColor(final TextColor color) {
this.fogColor = color;
}

public FogDensity getFogDensity() {
return this.fogDensity;
}

public void setFogDensity(final FogDensity density) {
this.fogDensity = density;
}

void setAdditionalSoundChance(final Script chance) {
this.additionalSoundChance = chance;
}
Expand Down Expand Up @@ -205,6 +218,7 @@ public void update(final BiomeConfigRule entry) {

entry.comment().ifPresent(this::addComment);
entry.fogColor().ifPresent(this::setFogColor);
entry.fogDensity().ifPresent(this::setFogDensity);
entry.additionalSoundChance().ifPresent(this::setAdditionalSoundChance);
entry.moodSoundChance().ifPresent(this::setMoodSoundChance);

Expand All @@ -219,23 +233,32 @@ public void update(final BiomeConfigRule entry) {
for (final AcousticConfig sr : entry.acoustics()) {
var factory = SOUND_LIBRARY.getSoundFactoryOrDefault(sr.factory());

Collection<AcousticEntry> targetCollection = null;
AcousticEntry acousticEntry = null;

switch (sr.type()) {
case LOOP -> {
final AcousticEntry acousticEntry = new AcousticEntry(factory, sr.conditions());
this.loopSounds.add(acousticEntry);
acousticEntry = new AcousticEntry(factory, sr.conditions());
targetCollection = this.loopSounds;
}
case MUSIC, MOOD, ADDITION -> {
final int weight = sr.weight();
final AcousticEntry acousticEntry = new AcousticEntry(factory, sr.conditions(), weight);
acousticEntry = new AcousticEntry(factory, sr.conditions(), weight);

if (sr.type() == SoundEventType.ADDITION)
this.additionalSounds.add(acousticEntry);
targetCollection = this.additionalSounds;
else if (sr.type() == SoundEventType.MOOD)
this.moodSounds.add(acousticEntry);
targetCollection = this.moodSounds;
else
this.musicSounds.add(acousticEntry);
targetCollection = this.musicSounds;
}
default -> LOGGER.warn("Unknown SoundEventType %s", sr.type());
default -> LOGGER.warn("[%s] Unknown SoundEventType %s", this.getBiomeName(), sr.type());
}

// Add if we have a target collection and it is not present
if (targetCollection != null) {
if (!targetCollection.add(acousticEntry))
LOGGER.warn("[%s] Duplicate acoustic entry: %s", this.getBiomeName(), sr.toString());
}
}
}
Expand Down Expand Up @@ -269,14 +292,18 @@ public String toString() {
builder.append("\nTags: ").append(tags);
builder.append("\n").append(getTraits().toString());

builder.append("\nfogDensity: ").append(this.fogDensity.getName());

if (this.fogColor != null) {
builder.append("\nfogColor: ").append(this.fogColor.formatValue());
builder.append(", fogColor: ").append(this.fogColor.formatValue());
}

if (!this.loopSounds.isEmpty()) {
builder.append("\nLOOP sounds [\n");
builder.append(this.loopSounds.stream().map(c -> indent + c.toString()).collect(Collectors.joining("\n")));
builder.append("\n]");
} else {
builder.append("\nLOOP sounds [NONE]");
}

if (!this.musicSounds.isEmpty()) {
Expand Down
Loading

0 comments on commit 4fbe3fa

Please sign in to comment.