Skip to content

Commit

Permalink
Added support for changing the volume and pitch of sounds when in cer…
Browse files Browse the repository at this point in the history
…tain biomes
  • Loading branch information
Sollace committed Dec 12, 2024
1 parent 294b2b4 commit 23c772e
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 8 deletions.
5 changes: 5 additions & 0 deletions src/main/java/eu/ha3/presencefootsteps/sound/Isolator.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import eu.ha3.presencefootsteps.util.JsonObjectWriter;
import eu.ha3.presencefootsteps.util.ResourceUtils;
import eu.ha3.presencefootsteps.util.BlockReport.Reportable;
import eu.ha3.presencefootsteps.world.BiomeVarianceLookup;
import eu.ha3.presencefootsteps.world.GolemLookup;
import eu.ha3.presencefootsteps.world.HeuristicStateLookup;
import eu.ha3.presencefootsteps.world.Index;
Expand All @@ -34,10 +35,12 @@ public record Isolator (
HeuristicStateLookup heuristics,
Lookup<EntityType<?>> golems,
Lookup<BlockState> blocks,
Index<Identifier, BiomeVarianceLookup.BiomeVariance> biomes,
Lookup<SoundEvent> primitives,
AcousticLibrary acoustics
) implements Reportable {
private static final Identifier BLOCK_MAP = PresenceFootsteps.id("config/blockmap.json");
private static final Identifier BIOME_MAP = PresenceFootsteps.id("config/biomevariancemap.json");
private static final Identifier GOLEM_MAP = PresenceFootsteps.id("config/golemmap.json");
private static final Identifier LOCOMOTION_MAP = PresenceFootsteps.id("config/locomotionmap.json");
private static final Identifier PRIMITIVE_MAP = PresenceFootsteps.id("config/primitivemap.json");
Expand All @@ -50,6 +53,7 @@ public Isolator(SoundEngine engine) {
new HeuristicStateLookup(),
new GolemLookup(),
new StateLookup(),
new BiomeVarianceLookup(),
new PrimitiveLookup(),
new AcousticsPlayer(new DelayedSoundPlayer(engine.soundPlayer))
);
Expand All @@ -58,6 +62,7 @@ public Isolator(SoundEngine engine) {
public boolean load(ResourceManager manager) {
boolean hasConfigurations = false;
hasConfigurations |= ResourceUtils.forEach(BLOCK_MAP, manager, blocks()::load);
hasConfigurations |= ResourceUtils.forEach(BIOME_MAP, manager, biomes()::load);
hasConfigurations |= ResourceUtils.forEach(GOLEM_MAP, manager, golems()::load);
hasConfigurations |= ResourceUtils.forEach(PRIMITIVE_MAP, manager, primitives()::load);
hasConfigurations |= ResourceUtils.forEach(LOCOMOTION_MAP, manager, locomotions()::load);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
* @author Hurry
*/
public interface StepSoundGenerator {

float getLocalPitch(float tickDelta);

float getLocalVolume(float tickDelta);

/**
* Gets the motion tracker used to determine the direction and speed for an entity during simulation.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.passive.AbstractHorseEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable;
Expand All @@ -15,11 +16,13 @@
import eu.ha3.presencefootsteps.config.Variator;
import eu.ha3.presencefootsteps.mixins.ILivingEntity;
import eu.ha3.presencefootsteps.sound.State;
import eu.ha3.presencefootsteps.util.Lerp;
import eu.ha3.presencefootsteps.util.PlayerUtil;
import eu.ha3.presencefootsteps.sound.Options;
import eu.ha3.presencefootsteps.sound.SoundEngine;
import eu.ha3.presencefootsteps.world.Association;
import eu.ha3.presencefootsteps.world.AssociationPool;
import eu.ha3.presencefootsteps.world.BiomeVarianceLookup;
import eu.ha3.presencefootsteps.world.Solver;
import eu.ha3.presencefootsteps.world.SoundsKey;
import eu.ha3.presencefootsteps.world.Substrates;
Expand Down Expand Up @@ -58,20 +61,40 @@ class TerrestrialStepSoundGenerator implements StepSoundGenerator {
protected final MotionTracker motionTracker = new MotionTracker(this);
protected final AssociationPool associations;

private final Lerp biomePitch = new Lerp();
private final Lerp biomeVolume = new Lerp();

public TerrestrialStepSoundGenerator(LivingEntity entity, SoundEngine engine, Modifier<TerrestrialStepSoundGenerator> modifier) {
this.entity = entity;
this.engine = engine;
this.modifier = modifier;
this.associations = new AssociationPool(entity, engine);
}

@Override
public float getLocalPitch(float tickDelta) {
return biomePitch.get(tickDelta);
}

@Override
public float getLocalVolume(float tickDelta) {
return biomeVolume.get(tickDelta);
}

@Override
public MotionTracker getMotionTracker() {
return motionTracker;
}

@Override
public void generateFootsteps() {
BiomeVarianceLookup.BiomeVariance variance = entity.getWorld().getBiome(entity.getBlockPos()).getKey().map(RegistryKey::getValue).map(key -> {
return engine.getIsolator().biomes().lookup(key);
}).orElse(BiomeVarianceLookup.BiomeVariance.DEFAULT);

biomePitch.update(variance.pitch(), 0.01F);
biomeVolume.update(variance.volume(), 0.01F);

motionTracker.simulateMotionData(entity);
simulateFootsteps();
simulateAirborne();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import eu.ha3.presencefootsteps.util.PlayerUtil;
import eu.ha3.presencefootsteps.sound.Options;
import eu.ha3.presencefootsteps.sound.SoundEngine;
import eu.ha3.presencefootsteps.sound.StepSoundSource;
import eu.ha3.presencefootsteps.sound.generator.StepSoundGenerator;

/**
* A Library that can also play sounds and default footsteps.
Expand Down Expand Up @@ -41,6 +43,13 @@ public void playSound(LivingEntity location, String soundName, float volume, flo
volume *= engine.getVolumeForSource(location);
pitch /= ((PlayerUtil.getScale(location) - 1) * 0.6F) + 1;

StepSoundGenerator generator = ((StepSoundSource) location).getStepGenerator(engine).orElse(null);
if (generator != null) {
float tickDelta = mc.getRenderTickCounter().getTickDelta(false);
volume *= generator.getLocalVolume(tickDelta);
pitch *= generator.getLocalPitch(tickDelta);
}

PositionedSoundInstance sound = new UncappedSoundInstance(soundName, volume, pitch, location);

if (distance > 100) {
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/eu/ha3/presencefootsteps/util/Lerp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package eu.ha3.presencefootsteps.util;

import net.minecraft.util.math.MathHelper;

public class Lerp {
public float previous;
public float current;

public void update(float newTarget, float rate) {
previous = current;
if (current < newTarget) {
current = Math.min(current + rate, newTarget);
}
if (current > newTarget) {
current = Math.max(current - rate, newTarget);
}
}

public float get(float tickDelta) {
return MathHelper.lerp(tickDelta, previous, current);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import org.jetbrains.annotations.Nullable;

import com.google.gson.JsonElement;

import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import net.minecraft.util.Identifier;

Expand Down Expand Up @@ -46,14 +48,14 @@ public Set<String> getSubstrates() {
}

@Override
public void add(String key, String value) {
public void add(String key, JsonElement value) {
final String[] split = key.trim().split("@");
final String primitive = split[0];
final String substrate = split.length > 1 ? split[1] : Substrates.DEFAULT;

substrates
.computeIfAbsent(substrate, s -> new Object2ObjectLinkedOpenHashMap<>())
.put(Identifier.of(primitive), SoundsKey.of(value));
.put(Identifier.of(primitive), SoundsKey.of(value.getAsString()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package eu.ha3.presencefootsteps.world;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.JsonElement;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import com.mojang.serialization.codecs.RecordCodecBuilder;

import eu.ha3.presencefootsteps.util.JsonObjectWriter;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;

public class BiomeVarianceLookup implements Index<Identifier, BiomeVarianceLookup.BiomeVariance> {
private final Map<Identifier, BiomeVariance> entries = new HashMap<>();

@Override
public BiomeVariance lookup(Identifier key) {
return entries.getOrDefault(key, BiomeVariance.DEFAULT);
}

@Override
public boolean contains(Identifier key) {
return entries.containsKey(key);
}

@Override
public void add(String key, JsonElement value) {
BiomeVariance.CODEC.decode(JsonOps.INSTANCE, value).result().map(Pair::getFirst).ifPresent(i -> {
entries.put(Identifier.of(key), i);
});
}

@Override
public void writeToReport(boolean full, JsonObjectWriter writer, Map<String, BlockSoundGroup> groups) throws IOException {
}

public record BiomeVariance(float volume, float pitch) {
public static final BiomeVariance DEFAULT = new BiomeVariance(1, 1);
static final Codec<BiomeVariance> CODEC = RecordCodecBuilder.create(i -> i.group(
Codec.FLOAT.fieldOf("volume").forGetter(BiomeVariance::volume),
Codec.FLOAT.fieldOf("pitch").forGetter(BiomeVariance::pitch)
).apply(i, BiomeVariance::new));
}
}
5 changes: 3 additions & 2 deletions src/main/java/eu/ha3/presencefootsteps/world/Loadable.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.Reader;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public interface Loadable {
Expand All @@ -11,7 +12,7 @@ public interface Loadable {
/**
* Register a blockmap entry.
*/
void add(String key, String value);
void add(String key, JsonElement json);

/**
* Loads new entries from the given config reader.
Expand All @@ -21,7 +22,7 @@ default void load(Reader reader) {
JsonObject json = GSON.fromJson(reader, JsonObject.class);

json.entrySet().forEach(entry -> {
add(entry.getKey(), entry.getValue().getAsString());
add(entry.getKey(), entry.getValue());
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import java.io.IOException;
import java.util.Map;

import com.google.gson.JsonElement;

public class LocomotionLookup implements Index<Entity, Locomotion> {
private final Map<Identifier, Locomotion> values = new Object2ObjectLinkedOpenHashMap<>();

Expand All @@ -36,14 +38,14 @@ public Locomotion lookup(Entity key) {
}

@Override
public void add(String key, String value) {
public void add(String key, JsonElement value) {
Identifier id = Identifier.of(key);

if (!Registries.ENTITY_TYPE.containsId(id)) {
PresenceFootsteps.logger.warn("Locomotion registered for unknown entity type " + id);
}

values.put(id, Locomotion.byName(value.toUpperCase()));
values.put(id, Locomotion.byName(value.getAsString().toUpperCase()));
}

@Override
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/eu/ha3/presencefootsteps/world/StateLookup.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

import org.jetbrains.annotations.Nullable;

import com.google.gson.JsonElement;

/**
* A state lookup that finds an association for a given block state within a specific substrate (or no substrate).
*
Expand All @@ -39,8 +41,8 @@ public SoundsKey getAssociation(BlockState state, String substrate) {
}

@Override
public void add(String key, String value) {
SoundsKey sound = SoundsKey.of(value);
public void add(String key, JsonElement value) {
SoundsKey sound = SoundsKey.of(value.getAsString());
if (!sound.isResult()) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"minecraft:pale_garden": {
"volume": 0.5,
"pitch": 1
}
}

0 comments on commit 23c772e

Please sign in to comment.