package vazkii.botania.common.block.subtile.functional;
import java.awt.Color;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.client.audio.ISound;
import net.minecraft.client.audio.ITickableSound;
import net.minecraft.client.audio.MovingSound;
import net.minecraft.client.audio.Sound;
import net.minecraft.client.audio.SoundEventAccessor;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraftforge.client.event.sound.PlaySoundEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.common.block.tile.mana.TilePool;
@SideOnly(Side.CLIENT)
public class BergamuteEventHandler {
private BergamuteEventHandler() {}
private static final Random RAND = new Random();
private static final float MULTIPLIER = 0.15F;
@SubscribeEvent(priority = EventPriority.LOWEST)
public static void onSoundEvent(PlaySoundEvent evt) {
ISound sound = evt.getResultSound();
if (sound != null && shouldSilence(sound)) {
if(sound instanceof ITickableSound) {
evt.setResultSound(new WrappedTickableSound((ITickableSound) sound, MULTIPLIER));
} else {
SubTileBergamute berg = SubTileBergamute.getBergamuteNearby(sound.getXPosF(), sound.getYPosF(), sound.getZPosF());
if (berg != null) {
evt.setResultSound(new WrappedSound(sound, MULTIPLIER));
if (RAND.nextBoolean()) {
Color color = TilePool.PARTICLE_COLOR;
BotaniaAPI.internalHandler.sparkleFX(berg.getWorld(), berg.getPos().getX() + 0.3 + Math.random() * 0.5, berg.getPos().getY() + 0.5 + Math.random() * 0.5, berg.getPos().getZ() + 0.3 + Math.random() * 0.5, color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, (float) Math.random(), 5);
}
}
}
}
}
private static boolean shouldSilence(ISound sound) {
return sound.getCategory() != SoundCategory.VOICE
&& sound.getCategory() != SoundCategory.MUSIC
&& sound.getClass().getName().startsWith("net.minecraft.client.audio");
}
@SideOnly(Side.CLIENT)
private static class WrappedSound implements ISound {
private final ISound compose;
private final float volMult;
private final boolean recheck;
private WrappedSound(ISound toWrap, float volMult) {
compose = toWrap;
this.volMult = volMult;
recheck = toWrap instanceof MovingSound;
}
@Override
public float getVolume() {
float mult = recheck && SubTileBergamute.getBergamuteNearby(getXPosF(), getYPosF(), getZPosF()) == null ? 1F : volMult;
return compose.getVolume() * mult;
}
@Nonnull @Override public ResourceLocation getSoundLocation() { return compose.getSoundLocation(); }
@Nullable @Override public SoundEventAccessor createAccessor(@Nonnull SoundHandler handler) { return compose.createAccessor(handler); }
@Nonnull @Override public Sound getSound() { return compose.getSound(); }
@Nonnull @Override public SoundCategory getCategory() { return compose.getCategory(); }
@Override public boolean canRepeat() { return compose.canRepeat(); }
@Override public int getRepeatDelay() { return compose.getRepeatDelay(); }
@Override public float getPitch() { return compose.getPitch(); }
@Override public float getXPosF() { return compose.getXPosF(); }
@Override public float getYPosF() { return compose.getYPosF(); }
@Override public float getZPosF() { return compose.getZPosF(); }
@Nonnull @Override public AttenuationType getAttenuationType() { return compose.getAttenuationType(); }
}
@SideOnly(Side.CLIENT)
private static class WrappedTickableSound extends WrappedSound implements ITickableSound {
private final ITickableSound compose;
private WrappedTickableSound(ITickableSound toWrap, float volMult) {
super(toWrap, volMult);
compose = toWrap;
}
@Override public boolean isDonePlaying() { return compose.isDonePlaying(); }
@Override public void update() { compose.update(); }
}
}