add fake block breaking and footstep sounds

This commit is contained in:
2026-05-26 10:53:19 +02:00
parent e0f4fb10fa
commit 0eaafd5ddc
@@ -5,6 +5,9 @@ import net.fretux.mindmotion.network.ModMessages;
import net.fretux.mindmotion.network.SyncStatsS2CPacket; import net.fretux.mindmotion.network.SyncStatsS2CPacket;
import net.fretux.mindmotion.player.PlayerCapabilityProvider; import net.fretux.mindmotion.player.PlayerCapabilityProvider;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.BiomeTags; import net.minecraft.tags.BiomeTags;
@@ -31,6 +34,30 @@ public class PlayerTickHandler {
private static final int SANITY_TICK_INTERVAL = 20; private static final int SANITY_TICK_INTERVAL = 20;
private static final int TEMPO_TICK_INTERVAL = 15; private static final int TEMPO_TICK_INTERVAL = 15;
private static final SoundEvent[] FAKE_MOB_SOUNDS = {
SoundEvents.ZOMBIE_AMBIENT,
SoundEvents.ENDERMAN_STARE,
SoundEvents.SPIDER_AMBIENT,
SoundEvents.CREEPER_PRIMED,
SoundEvents.HUSK_AMBIENT,
SoundEvents.WARDEN_ANGRY
};
private static final SoundEvent[] FAKE_BLOCK_BREAK_SOUNDS = {
SoundEvents.STONE_BREAK,
SoundEvents.DEEPSLATE_BREAK,
SoundEvents.GRASS_BREAK,
SoundEvents.GRAVEL_BREAK,
SoundEvents.WOOD_BREAK,
SoundEvents.GLASS_BREAK
};
private static final SoundEvent[] FAKE_FOOTSTEP_SOUNDS = {
SoundEvents.STONE_STEP,
SoundEvents.DEEPSLATE_STEP,
SoundEvents.GRASS_STEP,
SoundEvents.GRAVEL_STEP,
SoundEvents.WOOD_STEP,
SoundEvents.SAND_STEP
};
private static final Map<UUID, Integer> lastCombatTick = new ConcurrentHashMap<>(); private static final Map<UUID, Integer> lastCombatTick = new ConcurrentHashMap<>();
private static final Map<UUID, Integer> insanityDamageTicks = new ConcurrentHashMap<>(); private static final Map<UUID, Integer> insanityDamageTicks = new ConcurrentHashMap<>();
private static final Map<UUID, Integer> lowSanitySoundCooldown = new ConcurrentHashMap<>(); private static final Map<UUID, Integer> lowSanitySoundCooldown = new ConcurrentHashMap<>();
@@ -239,12 +266,13 @@ public class PlayerTickHandler {
applyBlackout(player); applyBlackout(player);
} }
} }
if (ConfigMM.COMMON.ENABLE_LOW_SANITY_SOUNDS.get() && percent <= 30f) { if (ConfigMM.COMMON.ENABLE_LOW_SANITY_SOUNDS.get() && (percent <= 30f || insanityPercent >= 35f)) {
UUID id = player.getUUID(); UUID id = player.getUUID();
int cd = lowSanitySoundCooldown.getOrDefault(id, 0) - SANITY_TICK_INTERVAL; int cd = lowSanitySoundCooldown.getOrDefault(id, 0) - SANITY_TICK_INTERVAL;
if (cd <= 0) { if (cd <= 0) {
playSanitySound(player); playSanitySound(player, percent, insanityPercent);
cd = 20 * (6 + player.getRandom().nextInt(15)); int baseSeconds = insanityPercent >= 60f || percent <= 10f ? 5 : 6;
cd = 20 * (baseSeconds + player.getRandom().nextInt(15));
} }
lowSanitySoundCooldown.put(id, cd); lowSanitySoundCooldown.put(id, cd);
} else { } else {
@@ -472,37 +500,51 @@ public class PlayerTickHandler {
player.addEffect(new MobEffectInstance(MobEffects.DARKNESS, 80, 0)); player.addEffect(new MobEffectInstance(MobEffects.DARKNESS, 80, 0));
} }
private static void playSanitySound(Player player) { private static void playSanitySound(Player player, float sanityPercent, float insanityPercent) {
var level = player.level(); var level = player.level();
if (level.isClientSide) return; if (level.isClientSide) return;
var sounds = new net.minecraft.sounds.SoundEvent[]{
net.minecraft.sounds.SoundEvents.ZOMBIE_AMBIENT, float pressure = Math.max(clamp01((30f - sanityPercent) / 30f), clamp01(insanityPercent / 100f));
net.minecraft.sounds.SoundEvents.ENDERMAN_STARE, int roll = player.getRandom().nextInt(100);
net.minecraft.sounds.SoundEvents.SPIDER_AMBIENT, if (roll < 45) {
net.minecraft.sounds.SoundEvents.CREEPER_PRIMED, SoundEvent chosen = pickSound(player, FAKE_MOB_SOUNDS);
net.minecraft.sounds.SoundEvents.HUSK_AMBIENT, playFakeSound(player, chosen, 4.0, 7.0, 0.0, 1.0f, 0.9f, 0.2f);
net.minecraft.sounds.SoundEvents.WARDEN_ANGRY } else if (roll < 72) {
}; SoundEvent chosen = pickSound(player, FAKE_BLOCK_BREAK_SOUNDS);
net.minecraft.sounds.SoundEvent chosen = playFakeSound(player, chosen, 2.5, 6.0, -0.5, 0.85f + pressure * 0.25f, 0.85f, 0.25f);
sounds[player.getRandom().nextInt(sounds.length)]; } else {
var holder = net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.wrapAsHolder(chosen); SoundEvent chosen = pickSound(player, FAKE_FOOTSTEP_SOUNDS);
float yaw = player.getYRot(); int steps = player.getRandom().nextFloat() < 0.35f + pressure * 0.35f ? 2 : 1;
double angleRad = Math.toRadians(yaw + 180 + player.getRandom().nextInt(40) - 20); for (int i = 0; i < steps; i++) {
double dist = 4.0 + player.getRandom().nextDouble() * 3.0; playFakeSound(player, chosen, 1.8 + i * 0.8, 4.2 + i * 0.8, -0.9, 0.65f, 0.8f, 0.35f);
double dx = player.getX() + Math.cos(angleRad) * dist; }
double dz = player.getZ() + Math.sin(angleRad) * dist;
double dy = player.getY();
if (player instanceof ServerPlayer sp) {
sp.connection.send(
new net.minecraft.network.protocol.game.ClientboundSoundPacket(
holder,
net.minecraft.sounds.SoundSource.AMBIENT,
dx, dy, dz,
1.0f,
0.9f + player.getRandom().nextFloat() * 0.2f,
player.getRandom().nextLong()
)
);
} }
} }
private static SoundEvent pickSound(Player player, SoundEvent[] sounds) {
return sounds[player.getRandom().nextInt(sounds.length)];
}
private static void playFakeSound(Player player, SoundEvent sound, double minDistance, double maxDistance,
double yOffset, float volume, float minPitch, float pitchRange) {
if (!(player instanceof ServerPlayer sp)) return;
var holder = net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.wrapAsHolder(sound);
float yaw = player.getYRot();
double angleRad = Math.toRadians(yaw + 180 + player.getRandom().nextInt(90) - 45);
double dist = minDistance + player.getRandom().nextDouble() * (maxDistance - minDistance);
double dx = player.getX() + Math.cos(angleRad) * dist;
double dz = player.getZ() + Math.sin(angleRad) * dist;
double dy = player.getY() + yOffset;
sp.connection.send(
new net.minecraft.network.protocol.game.ClientboundSoundPacket(
holder,
SoundSource.AMBIENT,
dx, dy, dz,
volume,
minPitch + player.getRandom().nextFloat() * pitchRange,
player.getRandom().nextLong()
)
);
}
} }