103 lines
3.1 KiB
Java
103 lines
3.1 KiB
Java
package net.minecraft.client.sounds;
|
|
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
|
import net.minecraft.client.resources.sounds.SoundInstance;
|
|
import net.minecraft.sounds.Music;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.RandomSource;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
/**
|
|
* The MusicManager class manages the playing of music in Minecraft.
|
|
*/
|
|
@Environment(EnvType.CLIENT)
|
|
public class MusicManager {
|
|
/**
|
|
* The delay before starting to play the next song.
|
|
*/
|
|
private static final int STARTING_DELAY = 100;
|
|
private final RandomSource random = RandomSource.create();
|
|
private final Minecraft minecraft;
|
|
@Nullable
|
|
private SoundInstance currentMusic;
|
|
/**
|
|
* The delay until the next song starts.
|
|
*/
|
|
private int nextSongDelay = 100;
|
|
|
|
public MusicManager(Minecraft minecraft) {
|
|
this.minecraft = minecraft;
|
|
}
|
|
|
|
/**
|
|
* Called every tick to manage the playing of music.
|
|
*/
|
|
public void tick() {
|
|
Music music = this.minecraft.getSituationalMusic();
|
|
if (this.currentMusic != null) {
|
|
if (!music.getEvent().value().location().equals(this.currentMusic.getLocation()) && music.replaceCurrentMusic()) {
|
|
this.minecraft.getSoundManager().stop(this.currentMusic);
|
|
this.nextSongDelay = Mth.nextInt(this.random, 0, music.getMinDelay() / 2);
|
|
}
|
|
|
|
if (!this.minecraft.getSoundManager().isActive(this.currentMusic)) {
|
|
this.currentMusic = null;
|
|
this.nextSongDelay = Math.min(this.nextSongDelay, Mth.nextInt(this.random, music.getMinDelay(), music.getMaxDelay()));
|
|
}
|
|
}
|
|
|
|
this.nextSongDelay = Math.min(this.nextSongDelay, music.getMaxDelay());
|
|
if (this.currentMusic == null && this.nextSongDelay-- <= 0) {
|
|
this.startPlaying(music);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Starts playing the specified {@linkplain Music} selector.
|
|
*
|
|
* @param selector the {@linkplain Music} selector to play
|
|
*/
|
|
public void startPlaying(Music selector) {
|
|
this.currentMusic = SimpleSoundInstance.forMusic(selector.getEvent().value());
|
|
if (this.currentMusic.getSound() != SoundManager.EMPTY_SOUND) {
|
|
this.minecraft.getSoundManager().play(this.currentMusic);
|
|
}
|
|
|
|
this.nextSongDelay = Integer.MAX_VALUE;
|
|
}
|
|
|
|
/**
|
|
* Stops playing the specified {@linkplain Music} selector.
|
|
*
|
|
* @param music the {@linkplain Music} selector to stop playing
|
|
*/
|
|
public void stopPlaying(Music music) {
|
|
if (this.isPlayingMusic(music)) {
|
|
this.stopPlaying();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stops playing the current {@linkplain Music} selector.
|
|
*/
|
|
public void stopPlaying() {
|
|
if (this.currentMusic != null) {
|
|
this.minecraft.getSoundManager().stop(this.currentMusic);
|
|
this.currentMusic = null;
|
|
}
|
|
|
|
this.nextSongDelay += 100;
|
|
}
|
|
|
|
/**
|
|
* {@return {@code true} if the {@linkplain Music} selector is currently playing, {@code false} otherwise}
|
|
*
|
|
* @param selector the {@linkplain Music} selector to check for
|
|
*/
|
|
public boolean isPlayingMusic(Music selector) {
|
|
return this.currentMusic == null ? false : selector.getEvent().value().location().equals(this.currentMusic.getLocation());
|
|
}
|
|
}
|